接口和抽象类的区别-java

接口和抽象类都是继承树的上层,他们的共同点如下:

1)  都是上层的抽象层。

2)  都不能被实例化

3)  都能包含抽象的方法,这些抽象的方法用于描述类具备的功能,但是不比提供具体的实现。

他们的区别如下:

1)  在抽象类中可以写非抽象的方法,从而避免在子类中重复书写他们,这样可以提高代码的复用性,这是抽象类的优势;接口中只能有抽象的方法。

2)  一个类只能继承一个直接父类,这个父类可以是具体的类也可是抽象类;但是一个类

可以实现多个接口。

Java语言中类的继承是单继承原因是:当子类重写父类方法的时候,或者隐藏父类的成员变量以及静态方法的时候,JVM使用不同的绑定规则。如果一个类有多个直接的父类,那么会使绑定规则变得更复杂。为了简化软件的体系结构和绑定机制,java语言禁止多继承。

接口可以多继承,是因为接口中只有抽象方法,没有静态方法和非常量的属性,只有接口的实现类才会重写接口中方法。因此一个类有多个接口也不会增加JVM的绑定机制和复杂度。

对于已经存在的继承树,可以方便的从类中抽象出新的接口,但是从类中抽象出新的抽象类就不那么容易了,因此接口更有利于软件系统的维护和重构。

首先接口和抽象类的设计目的就是不一样的。接口是对动作的抽象,而抽象类是对根源的抽象。对于抽象类,比如男人,女人这两个类,那我们可以为这两个类设计一个更高级别的抽象类--人。对于接口,我们可以坐着吃饭,可以站着吃饭,可以用筷子吃饭,可以用叉子吃饭,甚至可以学三哥一样用手抓着吃饭,那么可以把这些吃饭的动作抽象成一个接口--吃饭。

所以在高级语言中(如Java,C#),一个类只能继承一个抽象类(因为你不可能同时是生物又是非生物)。但是一个类可以同时实现多个接口,比如开车接口,滑冰接口,啪啪啪接口,踢足球接口,游泳接口。

总结几句话来说:

1、抽象类和接口都不能被直接实例化,如果二者要实例化,就涉及到多态,不懂多态的参见我的回答。如果抽象类要实例化,那么抽象类定义的变量必须指向一个子类对象,这个子类继承了这个抽象类并实现了这个抽象类的所有抽象方法。如果接口要实例化,那么这个接口定义的变量要指向一个子类对象,这个子类必须实现了这个接口所有的方法。

2、抽象类要被子类继承,接口要被子类实现。

3、接口里面只能对方法进行声明,抽象类既可以对方法进行声明也可以对方法进行实现。

4、抽象类里面的抽象方法必须全部被子类实现,如果子类不能全部实现,那么子类必须也是抽象类。接口里面的方法也必须全部被子类实现,如果子类不能实现那么子类必须是抽象类。

5、接口里面的方法只能声明,不能有具体的实现。这说明接口是设计的结果,抽象类是重构的结果。

6、抽象类里面可以没有抽象方法。

7、如果一个类里面有抽象方法,那么这个类一定是抽象类。

8、抽象类中的方法都要被实现,所以抽象方法不能是静态的static,也不能是私有的private。

9、接口(类)可以继承接口,甚至可以继承多个接口。但是类只能继承一个类。

10、抽象级别(从高到低):接口,抽象类,实现类。

11、抽象类主要是用来抽象类别,接口主要是用来抽象方法功能。当你关注事物的本质的时候,请用抽象类;当你关注一种操作的时候,用接口。

12、抽象类的功能应该要远多于接口,但是定义抽象类的代价较高。因为高级语言一个类只能继承一个父类,即你在设计这个类的时候必须要抽象出所有这个类的子类所具有的共同属性和方法;但是类(接口)却可以继承多个接口,因此每个接口你只需要将特定的动作方法抽象到这个接口即可。也就是说,接口的设计具有更大的可扩展性,而抽象类的设计必须十分谨慎。

先谈interface和class的区别,在C++里本来是没有interface,一个class可以从多个class派生。问题来了,当两个parent class都有相同方法时,调用这个class的方法会调用哪个parent class方法呢?这就是二义性问题。

Java于是禁止class的多重继承,引入了interface的概念,interface只是定义了行为特性的规约,没有实现,因此不会有二义性。

而abstractclass是有一些class仅仅作为parent使用,留有一些method给出了定义(在其他method中通常会调用),但没有实现,由不同的sub class来实现。这些method被标明为abstract(就不用提供mehod body),以便sub class要么实现这些方法,要么也作为abstract class。这样的class是无法被实例化的,因此需要标明为abstract class,以便编译时刻,编译器可以提示编译错误。

没有abstractmehod和abstract class可以不可以呢?也是可以的,只要在要求sub class实现的方法中添加method body,抛出MethodNotSupportedException,如果子类没有实现这个方法,自然会在运行时刻提示异常信息。怎么避免直接实例化这个类呢?可以把这个类的构造方法改为protected。

拿interface和abstract class来比,就是前者从概念上就不允许包括method body(Java 8又在interface上引入了default method,另说),后者主要是提供实现的,只不过提炼出了一些方法推延到subclass来实现。


发布了16 篇原创文章 · 获赞 69 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/xuaman/article/details/79523523