Java抽象类与接口

概念

抽象类是用来捕捉子类的通用特性的。它不能被实例化,只能被用作子类的超类。可以将抽象类当做是被用来创建继承层级里子类的模板。

接口是抽象方法的集合。如果一个类实现了某个接口,那么它就继承了这个接口的所有抽象方法,并需要确保这些方法全部实现,这就像是契约模式一般。接口只是一种形式,接口自身不能做任何事情。

在Java中,一个类只能够继承一个抽象类,但是一个类可以同时实现多个接口。

设计思想

从概念上,可知抽象类与接口所设计的目的是不一样的 —— 接口是对动作的抽象,而抽象类是对根源的抽象

举个例子而言,在这个世界上存在很多不同的车,跑车、轿车、货车等,那么对于抽象类而言,我们就需要从这些车中提取它们的公共部分,设计出一个更高级别的抽象类——四轮车。

但轿车与货车同为四轮车,但是普遍轿车都存在着自动驾驶功能,如果货车需要自动驾驶功能的话,那么对于接口而言,可以把自动驾驶功能所需的这些方法抽象成接口——自动驾驶。

如何选择

从程序设计中,如何选择抽象类与接口?从我的观点而言,在程序设计中我们需要考虑的是高度抽象化以及程序可扩展性。

因为在Java中只能够继承一个父类,所以定义抽象类的代价比较高。即在程序设计中,需要从自下至上,综合分析所有子类中的共同点,高度抽象化成父类(这里可以联想Object,即使不是抽象类,但它却由始至终贯穿整个java体系)。

但相比于抽象类而言,接口所付出的代价相对的低很多,可扩展性也大大提高了,因为类可以实现多个接口,因此每个接口你只需要将特定的动作抽象到这个接口即可。

举个例子,如LinkedList的继承体系一般。

1
2
3
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
  • 抽象类的角度。LinkedList继承自AbstractSequentialList,这说明了LinkedList属于链表这种数据结构的继承体系中,它继承了所有链表的基本操作。
  • 接口的角度。LinkedList实现了Deque接口,这表明了即使是链表,也能够实现双端队列的功能,使程序调用者可以将LinkedList同等视为队列使用。

参考资料

接口和抽象类有什么区别?

Java抽象类与接口的区别