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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© noiary 高级黑马   /  2014-9-10 23:32  /  9655 人查看  /  22 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 noiary 于 2014-9-11 13:26 编辑

如题,手机发帖打字好费劲。
============================================================================================================


看过小伙伴儿们回复后,我想我大概明白了.

接口里面全部都是抽象方法,没有变量数据,是一种行为规范而不是具体行为,所以没必要创建对象,也就不需要构造方法.

这是第二个问题来了, 抽象类也不能创建对象,但却可以有构造方法....

我自己也百度了一下,看完一篇文章后若有感悟,但还是似懂非懂,貌似在具体开发中,选择抽象类还是接口,这是个很复杂的问题.  

好在,解决问题是我们前进的动力,一起加油!

从语法角度谈抽象类与接口区别
        在另一博文中 ‍http://hi.baidu.com/gabe2008/blog/item/a3f201ce9412df37f9dc61d4.html 以举例的方式说到如何区分抽象类和接口,这里我们从Java语法谈起,使我们更加了解这两者的内在区别。它们的语法区别:1)接口不能有构造方法,抽象类可以有。2)接口不能有方法体,抽象类可以有。3)接口不能有静态方法,抽象类可以有。4)在接口中凡是变量必须是public static final,而在抽象类中没有要求。
       忽然有此一文,是因为同学疑惑道:抽象类居然还有构造方法,又不能直接用来new。我的解释是平时在抽象类中对于构造方法的存在,没有什么印象,是因为IDE默认为你生成了一个无参构造方法,也可以显式地写出构造方法,这个构造方法,是用来被子类调用的,因为任何子类都必须调用从Object开始的所有父亲的构造方法,才算完成初始化工作。那么我引申一下,问他们,接口有构造方法吗?他们的理解,抽象可以有,为什么接口不可以有?!那么在接口里写入构造方法时,编译器提示:Interfaces cannot have constructors。这又何解?
        从语法的角度来说,抽象类必须有构造方法,而接口严禁有构造方法,这本身也说明了它们性质的不同。抽象类是一个类,别的类是用关键字 extends 来继承下来,并扩展的,有非常强的is-a的关系,这种关系一般来说符合里氏代换原则。而接口,是被其他类用关键字 implements 来实现接口定义的方法的。如果没什么区别,何必整出两个不同的关键字。   接口只是定义功能和行为规范,如果一个类实现了一个接口,那么这个类必须遵守这个接口的方法约定,但没有is-a的关系。把墙壁上的“小学生行为规范”想象成一个接口,那么是小学生必须遵守这个约定,但小学生不是“行为规范”。
       构造方法是用来在对象初始化前对对象进行一些预处理的,提供了实例化一个具体东西的入口。接口只是声明而已,不一定要进行什么初始化,就算要进行初始化,也可以到实现接口的那一些类里面去初始化。接口只是用来表述动作,表述规范来的,可以new一台computer,但我们无法new一个IDE、SATA、PCI、PS-2。因此,接口要构造方法何用?接口是一种规范,被调用时,主要关注的是里边的方法,而方法是不需要初始化的,类可以实现多个接口,若多个接口都有自己的构造器,则不好决定构造器的调用次序,构造器是属于类自己的,不能继承,因为是纯虚的,接口不需要构造方法。而抽象类是具体类的祖先,即使是石器时代,也总要干些初始化的工作,抽象类虽然是不能直接实例化,但实例化子类的时候,就会初始化父类,不管父类是不是抽象类都,都会调用父类的构造方法,初始化一个类,先初始化父类,有没有说初始化接口。
        再拿汽车的例子来说明两者的区别,Car, Track, Van 是 Vehicle 抽象类的子类,那么你可以说小娇车是车子,拖拉机是车子,货车是车子。而做为他们共同的父类,会做一些初始化工作,如加汽油、机油、冷却液。另外所有车子具有共同属性,轮子,方向盘,油门等。Brake 是一个刹车动作接口,这个规范要求车子实现了它,必须有能力把速度减到零,只是实现途径不一样,或者是鼓刹,或者是碟刹。或者是效果不一样,有的刹车灵一点,有的刹车差一点。
        在抽象类和接口均可以被考虑的地方,接口首先是被提倡使用的,在语法上没有is-a的关系,使用起来更加灵活,另外可以多实现毕竟是一种难得的资源。而抽象类当存在大家共同的实现方法,或者有很多属性操作时,才是首选,当考虑使用抽象类时,在可预见的未来,它要体现出被继承时非常强烈的is-a关系。
       接口不能有方法体,就是强制接口定义者不能给接口增加一些详细的实现,指定的必须是纯虚的接口,对于架构者来说,它需要做的就是定义一个可以理解的接口名,参数列表,以及返回类型。而抽象类是可以有自己的实现方法,这个方法可以被用来被执行。有时候,我们会误以为抽象类中的方法不能用super显示调用,因为super是指代父类对象,而抽象类MS不能有对象。但事实上可以,任何子类实际的对象,都可以理解成父类的对象。
        接口的所有方法都是抽象的,而抽象方法是没有static,有static的方法是不能override的,不能实现多态,所以这样定义接口才有意义,接口中定义的方法目的很明确:就是给实现类去实现,如果你在接口中将方法声明为静态的(与具体的实例无关),但接口中的方法又要求必须被实现类去实现(可能会有多个实现类),这岂不是自相矛盾!如果硬要加上static上去,编译器会友好提示:Illegal modifier for the interface method FF.f(); only public & abstract are permitted。说到底,不能再加任何除public 和 abstract 的任何修饰符了,如:private, protected, final, static.
       数据成员没有多态的概念,只有可不可以被访问的说法,如果是公有的数据成员是在任何地方都可以被访问和修改的,那么接口定义的数据成员如果是私有的,又何必定义,因为它没有方法,就是说没有任何方法对这个数据成员可以操作。如果是公有的,谁都可以修改,那么,多重实现多个接口,这个数据不是改得乱了套?所以接口一般不允许有数据成员,但如果真的有,明确默认即为public final static, 严格保证对于所有实现者来说只有一份原始的数据。
        那么在架构设计时,如何使用抽象类和接口来解决问题,是一个非常复杂的问题,抽象类更侧重于归纳同一父类的子类的共同特征,如果属性,方法;接口更侧重于定义任意的类有没有相同语义的方法,它是一个一经定义不轻易更改的规范,它的修改在项目中,往往是动一发而牵全身,即使有考虑不周到的地方,也会使用新增接口的形式去弥补。其实abstract class表示的是"is-a"关系,interface表示的是"like-a"关系。最顶级的是接口,然后是抽象类实现接口,最后才到具体类实现。



22 个回复

倒序浏览
主要是不让其他类创建对象。
回复 使用道具 举报
接口里都是抽象函数,不能创建对象,
回复 使用道具 举报 1 0
为啥要有呢?
回复 使用道具 举报
接口是抽象的,是不能建立对象的。
当然就不能有构造函数啊
回复 使用道具 举报
抽象不能实例化
回复 使用道具 举报
不能new接口,自然不用构造了
回复 使用道具 举报
接口里面的都是抽象的方法,是叫实现该接口的子类去实现的方法,而构造函数是用于对象实例的初始化,如果接口有了构造函数的话就可以创建它的实例对象,但创建一个没有具体内部构造的实例是没有任何意义的。
所以接口不允许有构造函数

点评

赞!  发表于 2014-9-11 12:22
回复 使用道具 举报
最重要的是要明白接口是什么,接口是一个承诺,就好比一个人说:我明天12点到北京。那么明天12点只要他出现在北京就算完成了承诺,使用什么工具去,开车还是飞机,接口就管不着了。
所以,接口的作用就是让一个类做出承诺,如何实现由类来完成。
而构造函数的作用是生成一个对象,而只有类才能生成对象,所以接口不会有构造函数。
回复 使用道具 举报

因为说不能有,会有疑问,为什么没有.
回复 使用道具 举报
卖艺人 发表于 2014-9-11 11:04
接口是抽象的,是不能建立对象的。
当然就不能有构造函数啊

抽象类也是抽象的....
回复 使用道具 举报
darkads 发表于 2014-9-11 11:41
最重要的是要明白接口是什么,接口是一个承诺,就好比一个人说:我明天12点到北京。那么明天12点只要他出现 ...

好棒的比喻,我好像明白了!
回复 使用道具 举报
逍遥呆 发表于 2014-9-11 01:10
主要是不让其他类创建对象。

嗯,看完各位的评论,我好像明白了!
回复 使用道具 举报
本帖最后由 noiary 于 2014-9-11 12:39 编辑
likeermei 发表于 2014-9-11 11:18
接口里面的都是抽象的方法,是叫实现该接口的子类去实现的方法,而构造函数是用于对象实例的初始化,如果接 ...

但抽象类不一定全是抽象方法,从而抽象类内部可能存在具体方法,所以抽象类是可以创建实例,所以抽象类有构造方法而接口没有. 可以这样理解吧
啊不对, 抽象类也不可以创建对象,那抽象类为什么可以有构造方法呢?
回复 使用道具 举报
noiary 发表于 2014-9-11 12:29
但抽象类不一定全是抽象方法,从而抽象类内部可能存在具体方法,所以抽象类是可以创建实例,所以抽象类有构造 ...

抽象类可以有具体方法,new抽象类的对象可以调用抽象类中定义的具体方法,而接口里面没有具体方法,所以就算创建了他的对象也是没有用的
回复 使用道具 举报
沙拉很好吃 发表于 2014-9-11 11:15
不能new接口,自然不用构造了

那你怎么解释抽象类里面的构造方法呢,这个解释太牵强了
回复 使用道具 举报
双皮奶 发表于 2014-9-11 13:21
那你怎么解释抽象类里面的构造方法呢,这个解释太牵强了

嗯嗯,我也是被这个问题迷惑.
回复 使用道具 举报
noiary 发表于 2014-9-11 12:21
抽象类也是抽象的....

我的错,说得不准确,接口只是声明方法,不能实现方法。
因此接口里面的方法必须都是抽象的。而抽象类可以有一部分方法是非抽象的。
构造方法也是一种方法,而且一定有方法体,没见过抽象的构造方法。

至于抽象类为什么有构造方法,应该是一切类都有构造方法, 再说抽象类的子类实现了抽象类的方法,当子类创建对象的时候一定要调用父类的构造方法。因此抽象类中一定有构造方法。
回复 使用道具 举报
卖艺人 发表于 2014-9-11 21:33
我的错,说得不准确,接口只是声明方法,不能实现方法。
因此接口里面的方法必须都是抽象的。而抽象类可 ...

恩恩~                                      
回复 使用道具 举报
大神回答的不错  学习了
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马