A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 丁倩 黑马帝   /  2011-8-4 23:58  /  2404 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

对于抽象类和接口还是有点不明白,接口到底有什么作用啊?书上说的是:接口的设计目的是为了让类不必受限与单一继承的关系,而可以灵活的同时继承一些公有的特性,从而达到多重继承的目的。我有点不明白,实现一个接口必须要实现里面所有的方法,但是我也可以不去实现这个接口,自己在类中直接实现相应的方法,这样做和implements一个接口有什么不一样啊?接口到底有什么作用啊?

评分

参与人数 1技术分 +2 收起 理由
老罗 + 2 经典问题

查看全部评分

5 个回复

正序浏览
黑马网友  发表于 2011-8-5 18:29:40
地板

张老师在宝典中的回答

abstract class和interface有什么区别?        
含有abstract修饰符的class即为抽象类,abstract 类不能创建的实例对象。含有abstract方法的类必须定义为abstract class,abstract class类中的方法不必是抽象的。abstract class类中定义抽象方法必须在具体(Concrete)子类中实现,所以,不能有抽象构造方法或抽象静态方法。如果的子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型。
接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。
下面比较一下两者的语法区别:
1.抽象类可以有构造方法,接口中不能有构造方法。
2.抽象类中可以有普通成员变量,接口中没有普通成员变量
3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
4. 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然
eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
5. 抽象类中可以包含静态方法,接口中不能包含静态方法
6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。
7. 一个类可以实现多个接口,但只能继承一个抽象类。
        下面接着再说说两者在应用上的区别:
接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约。而抽象类在代码实现方面发挥作用,可以实现代码的重用,例如,模板方法设计模式是抽象类的一个典型应用,假设某个项目的所有Servlet类都要用相同的方式进行权限判断、记录访问日志和处理异常,那么就可以定义一个抽象的基类,让所有的Servlet都继承这个抽象基类,在抽象基类的service方法中完成权限判断、记录访问日志和处理异常的代码,在各个子类中只是完成各自的业务逻辑代码,伪代码如下:
public abstract class BaseServlet extends HttpServlet
{
                public final void service(HttpServletRequest request, HttpServletResponse response) throws IOExcetion,ServletException
                {
                        记录访问日志
                        进行权限判断
if(具有权限)
{
        try
        {
                doService(request,response);
}
        catch(Excetpion e)
        {
                        记录异常信息
        }
}
                }
                protected abstract void doService(HttpServletRequest request, HttpServletResponse response) throws IOExcetion,ServletException;  
//注意访问权限定义成protected,显得既专业,又严谨,因为它是专门给子类用的
}

public class MyServlet1 extends BaseServlet
{
protected void doService(HttpServletRequest request, HttpServletResponse response) throws IOExcetion,ServletException
                {
                        本Servlet只处理的具体业务逻辑代码
                }

}
父类方法中间的某段代码不确定,留给子类干,就用模板方法设计模式。
备注:这道题的思路是先从总体解释抽象类和接口的基本概念,然后再比较两者的语法细节,最后再说两者的应用区别。比较两者语法细节区别的条理是:先从一个类中的构造方法、普通成员变量和方法(包括抽象方法),静态变量和方法,继承性等6个方面逐一去比较回答,接着从第三者继承的角度的回答,特别是最后用了一个典型的例子来展现自己深厚的技术功底。

评分

参与人数 1技术分 +2 收起 理由
老罗 + 2

查看全部评分

回复 使用道具 举报
黑马网友  发表于 2011-8-5 17:59:40
报纸

回复楼主

接口是公开的,里面不能有私有的方法或变量,是用于让别人使用的,而抽象类是可以有私有方法或私有变量的,

另外,实现接口的一定要实现接口里定义的所有方法,而实现抽象类可以有选择地重写需要用到的方法,一般的应用里,最顶级的是接口,然后是抽象类实现接口,最后才到具体类实现。

还有,接口可以实现多重继承,而一个类只能继承一个超类,但可以通过继承多个接口实现多重继承,接口还有标识(里面没有任何方法,如Remote接口)和数据共享(里面的变量全是常量)的作用.

评分

参与人数 1技术分 +1 收起 理由
老罗 + 1

查看全部评分

回复 使用道具 举报
黑马网友  发表于 2011-8-5 09:27:40
板凳
把这个接口 可以比喻成电脑主机的鼠标接口吧  
其实你有一种方法 我不用接口 直接 用铜线连起来 鼠标也能懂
但是如果我用了 USB 接口 就不一样了 各式各样的鼠标 红外的 激光的 小熊的 大熊的 粉色的 蓝色的 一插就得  这多方便啊  而且还有很多不同的 功能  调节鼠标指针速度啊 上网前进后退啊 呵呵
这样说了 这么多好处 谁不用接口 还自己接线去啊

评分

参与人数 1技术分 +1 收起 理由
老罗 + 1

查看全部评分

回复 使用道具 举报
黑马网友  发表于 2011-8-5 02:38:57
藤椅
可以将类看着一个男人,他是能干活的,只要new出来,就能用。
可以将接口看着一个女人,他是搞关系的,必须依赖别人的实着它才能用。
但是越是使劲干活的,就难免显得笨拙,所以它的关系不多,只能单传,当然,这也很符合我国的传统啊。
接口嘛,虽然只说不做,但是其却显得很灵活,她不仅可以团结一切愿意实现她的实体,更重要的可以作为实体交互的润滑剂。
。。。。瞎耻了,哈哈,我知道你没听懂。说实在的,这玩意知道和理解那真是天壤之别,只可意会,不可言传啊。

评分

参与人数 1技术分 +2 收起 理由
老罗 + 2 可以嘛!

查看全部评分

回复 使用道具 举报
继承就是把共性内容不断向上抽取而来的,例如你老爸有100万,这时候你要用你就不用去挣100万了直接从老爸那里继承过来! 而接口呢就类似你老爸这里有个挣钱的方法,而你又比较独立然后自己根据老爸给你的挣钱方法去挣这100万
按照我的理解可能会给你增加更多的困惑,这是毕向东老师的总结的文档,希望你看了会更了解
面向对象的第二特征:
继承:
        好处:
        1,提高了代码的复用性。
        2,让类与类之间产生了关系。有了这个关系才有了多态的出现。

java只支持单继承,不支持多继承(其实java保留了多继承机制,
但是多继承容易出现问题,用另一种方式来体现--多实现)。

java支持多层继承。
其实就是一个继承体系。
继承体系何来?其实都是通过对事物的分析,将共性内容不断向上抽取而来的。

想要对一个继承体系的功能进行使用时,可以参考一个技巧。
查阅顶层父类中的方法。因为这里的方法都是共性方法。
建立该体系中最子类的对象。
如果需要使用子类特有方法时,才需要查看子类的方法。


什么时候定义继承呢?

当类与类之间存在所属(is a)关系时,就可以定义继承。
如何判断所属关系呢?一个类是否可以获取到另一个类中所有的内容,如果可以,那么可以继承。

class DemoA
{
        void showA(){}
        void showB(){}
        void showC(){}
}


//DemoB中也有一个showC()方法。那么DemoA中已经定义好了,可不可以直接继承过来用呢?
//很遗憾,showA(),showB(),并不是适合DemoB,也就是DemoB中不可以有showA(),showB()
class DemoB
{
        void showC(){}
        void showD(){}
}


//虽然DemoB不可以继承DemoA,但是发现他们有共性方法。那么可以继续向上抽取。
class Demo
{
        void showC(){}
}

class DemoA extends Demo
{
        void showA(){}
        void showB(){}
}
class DemoB extends Demo
{
        void showD(){}
}
接口:
        特点:
        1,接口用于功能的扩展。
        2,接口其实就是对外暴露的规则。
        3,接口的出现降低了藕合性。
        比如:笔记本usb接口,主板的pci接口。mp3,手机,插排。

        好处:
        接口的出现,保留了多继承的机制,用多实现来表示。
        而且接口可以多继承接口。
        一个类在继承一个类的同时,可以实现多个接口。

        代码规则:
        使用interface关键字定义的。编译后生成的是.class文件。
        接口中通常的成员:常量。抽象方法。
        而且这些成员的有固定的修饰符。
        常量:public static final。
        方法:public abstract
        interface Demo
        {
                int x= 3;
                void show();.//不些这些固定修饰符,系统会自动加上。
        }
        但是要注意,复写接口中的方法的时候,一定要加上public。

        类与接口之间是实现关系implements。
        一个类必须实现接口中所有的方法后,才可以被实例化,否则该类还是一个抽象类。


----------------------------------------

        抽象类和接口的不同。
        学员示例。

        abstract class XueYuan
        {
                public void sleep()
                {}

                public abstract  void study();
               
        }

        interface Play
        {
                void play();
        }

        class Zhangsan extends XuYuan implements Play
        {
                public void study(){}
                public void play(){}               
        }

        问题领域。在分析事物时,值考虑该事物领域内的内容。
        那么对于打球方法,并不是该领域的基本方法。这时把该功能扩展出去。通过接口来完成。



        球员示例。
        abstract class QiuYuan
        {
                abstract void play();

        }
        interface Study
        {
                void study();
        }

        class Wangwu extends QiuYuan implements Study
        {
                void play(){}
                void study(){}
        }
接口的应用:
        编写一个项目,该项目应用到了数据库(mysql)
        到了后期,软件有了新的需求,使用Oracle数据库。
               
        对数据库的操作常见的四种操作,增 删 改 查。
        class SqlOperate
        {
                public void add()
                {
                        mysql code;
                }
                public void del()
                {
                        mysql code;
                }
        }

        换成oracle就需要该动SqlOperate该类中的方法内容。
        后期维护不建议该动代码,灾难。

        在前期分析的时候,就应该考虑到这样需求。
        为了后期扩展方便,留有扩展余地,进行功能的扩展。

        interface SqlDao
        {
                public void add();
                public void del();
        }
        class MySqlOperate implements SqlDao
        {
                public void add()
                {
                        mysql code;
                }
                public void del()
                {
                        mysql code;
                }
        }
        到了后期变成oracle时,
        只需要在定义一个类去重新实现接口即可。
        class OracleSqlOperate implements SqlDao
        {
                public void add()
                {
                        Oracle code;
                }
                public void del()
                {
                        Oracle code;
                }
        }
[ 本帖最后由 王士铭 于 2011-08-05  02:38 编辑 ]

评分

参与人数 1技术分 +2 收起 理由
老罗 + 2 辛苦了,加分。

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马