接口和抽象类都是继承树的上层,他们的共同点如下:
都是上层的抽象层。
都不能被实例化
都能包含抽象的方法,这些抽象的方法用于描述类具备的功能,但是不比提供具体的实现。
他们的区别如下:
在抽象类中可以写非抽象的方法,从而避免在子类中重复书写他们,这样可以提高代码的复用性,这是抽象类的优势;接口中只能有抽象的方法。
一个类只能继承一个直接父类,这个父类可以是具体的类也可是抽象类;但是一个类可以实现多个接口。
Java语言中类的继承是单继承原因是:当子类重写父类方法的时候,或者隐藏父类的成员变量以及静态方法的时候,JVM使用不同的绑定规则。如果一个类有多个直接的父类,那么会使绑定规则变得更复杂。为了简化软件的体系结构和绑定机制,java语言禁止多继承。
接口可以多继承,是因为接口中只有抽象方法,没有静态方法和非常量的属性,只有接口的实现类才会重写接口中方法。因此一个类有多个接口也不会增加JVM的绑定机制和复杂度。对于已经存在的继承树,可以方便的从类中抽象出新的接口,但是从类中抽象出新的抽象类就不那么容易了,因此接口更有利于软件系统的维护和重构。
图中如果Sparrow继承类Bird 类 ,Boyin继承Airplane类,Sparrow 和Boyin想使用同样的flay方法那么是没有办法实现的,因为类的继承是单继承。
如果Bird和Airplane是接口那么Boyin想使用同样的flay方法就很简单了。在写一个接口让Sparrow和Boyin实现这个接口就可以了如下图:
首先接口和抽象类的设计目的就是不一样的。接口是对动作的抽象,而抽象类是对根源的抽象。对于抽象类,比如男人,女人这两个类,那我们可以为这两个类设计一个更高级别的抽象类--人。对于接口,我们可以坐着吃饭,可以站着吃饭,可以用筷子吃饭,可以用叉子吃饭,甚至可以学三哥一样用手抓着吃饭,那么可以把这些吃饭的动作抽象成一个接口--吃饭。所以在高级语言中(如Java,C#),一个类只能继承一个抽象类(因为你不可能同时是生物又是非生物)。但是一个类可以同时实现多个接口,比如开车接口,滑冰接口,啪啪啪接口,踢足球接口,游泳接口。
总结几句话来说:
1、抽象类和接口都不能被直接实例化,如果二者要实例化,就涉及到多态,不懂多态的参见我的回答JAVA的多态用几句话能直观的解释一下吗? - 知乎。如果抽象类要实例化,那么抽象类定义的变量必须指向一个子类对象,这个子类继承了这个抽象类并实现了这个抽象类的所有抽象方法。如果接口要实例化,那么这个接口定义的变量要指向一个子类对象,这个子类必须实现了这个接口所有的方法。
2、抽象类要被子类继承,接口要被子类实现。
3、接口里面只能对方法进行声明,抽象类既可以对方法进行声明也可以对方法进行实现。
4、抽象类里面的抽象方法必须全部被子类实现,如果子类不能全部实现,那么子类必须也是抽象类。接口里面的方法也必须全部被子类实现,如果子类不能实现那么子类必须是抽象类。
5、接口里面的方法声明,不能有具体的实现。这说明接口是设计的结果,抽象类是重构的结果。
6、抽象类里面可以没有抽象方法。
7、如果一个类里面有抽象方法,那么这个类一定是抽象类。
8、抽象类中的方法都要被实现,所以抽象方法不能是静态的static,也不能是私有的private。
9、接口(类)可以继承接口,甚至可以继承多个接口。但是类只能继承一个类。
10、抽象级别(从高到低):接口>抽象类>实现类。
11、抽象类主要是用来抽象类别,接口主要是用来抽象方法功能。当你关注事物的本质的时候,请用抽象类;当你关注一种操作的时候,用接口。
12、抽象类的功能应该要远多于接口,但是定义抽象类的代价较高。因为高级语言一个类只能继承一个父类,即你在设计这个类的时候必须要抽象出所有这个类的子类所具有的共同属性和方法;但是类(接口)却可以继承多个接口,因此每个接口你只需要将特定的动作方法抽象到这个接口即可。也就是说,接口的设计具有更大的可扩展性,而抽象类的设计必须十分谨慎。
抽象类-->像xxx一样接 口-->能xxx这样
接口中所有的方法隐含的都是抽象的。而抽象类则可以同时包含抽象和非抽象的方法。
类可以实现很多个接口,但是只能继承一个抽象类
类如果要实现一个接口,它必须要实现接口声明的所有方法。但是,类可以不实现抽象类声明的所有方法,当然,在这种情况下,类也必须得声明成是抽象的。
抽象类可以在不提供接口方法实现的情况下实现接口。
Java接口中声明的变量默认都是final的。抽象类可以包含非final的变量。
Java接口中的成员函数默认是public的。抽象类的成员函数可以是private,protected或者是public。
接口是绝对抽象的,不可以被实例化。抽象类也不可以被实例化,但是,如果它包含main方法的话是可以被调用的。