接口与抽象类是Java中定义的两种特殊类,两者之间最大的不同在于:
-
接口中所有方法都没有被实现,而抽象类中存在抽象方法(没有方法体),也存在静态方法和变量。
因此为了实例化继承他们的子类,接口中所有方法都必须被实现,而抽象类中的所有抽象方法都必须被实现,如果有一个抽象方法没有被实现,那么子类仍然是一个抽象类,不能被实例化。 -
在继承中两者也有所不同,在Java中,类只允许单继承,也就是一个子类只能继承一个直接父类,抽象类也是如此。但一个类可以同时实现多个接口。
我看到一个之所以这样设计继承的原因,是说在抽象类(或其他正常类)中有静态方法,如果是多继承中多个父类中有相同名字的静态方法,但实现有所不同,就会出现这个静态方法的二义性,但接口中没有静态方法,这种情况就不会出现。
题外话1:
但在python和C++中就支持多继承,如果 C extends A, B
, 那么会优先继承A, 然后再继承B,并没有二义性。
题外话2:
在C++中有一个很相似的话题,虚函数和纯虚函数有何不同。
虚函数并不代表没有被实现,定义虚函数是为了用基类的指针来调用父类的函数,是一种实现多态的方式。虚函数在子类中也必须被实现,如果不实现会报错。对虚函数来说,有子类和基类不同的版本,由多态调用时动态绑定。虚函数用关键字virtual
定义。
纯虚函数是没有被实现的,要求任何派生类都必须实现它。包含纯虚函数的类为抽象类。定义方法是在函数后面加=0
.
virtual void function1() = 0;