Java抽象类与接口
概念
抽象类是用来捕捉子类的通用特性的。它不能被实例化,只能被用作子类的超类。可以将抽象类当做是被用来创建继承层级里子类的模板。
接口是抽象方法的集合。如果一个类实现了某个接口,那么它就继承了这个接口的所有抽象方法,并需要确保这些方法全部实现,这就像是契约模式一般。接口只是一种形式,接口自身不能做任何事情。
在Java中,一个类只能够继承一个抽象类,但是一个类可以同时实现多个接口。
设计思想
从概念上,可知抽象类与接口所设计的目的是不一样的 —— 接口是对动作的抽象,而抽象类是对根源的抽象。
举个例子而言,在这个世界上存在很多不同的车,跑车、轿车、货车等,那么对于抽象类而言,我们就需要从这些车中提取它们的公共部分,设计出一个更高级别的抽象类——四轮车。
但轿车与货车同为四轮车,但是普遍轿车都存在着自动驾驶功能,如果货车需要自动驾驶功能的话,那么对于接口而言,可以把自动驾驶功能所需的这些方法抽象成接口——自动驾驶。
如何选择
从程序设计中,如何选择抽象类与接口?从我的观点而言,在程序设计中我们需要考虑的是高度抽象化以及程序可扩展性。
因为在Java中只能够继承一个父类,所以定义抽象类的代价比较高。即在程序设计中,需要从自下至上,综合分析所有子类中的共同点,高度抽象化成父类(这里可以联想Object,即使不是抽象类,但它却由始至终贯穿整个java体系)。
但相比于抽象类而言,接口所付出的代价相对的低很多,可扩展性也大大提高了,因为类可以实现多个接口,因此每个接口你只需要将特定的动作抽象到这个接口即可。
举个例子,如LinkedList
的继承体系一般。
1 | public class LinkedList<E> |
- 抽象类的角度。
LinkedList
继承自AbstractSequentialList
,这说明了LinkedList
属于链表这种数据结构的继承体系中,它继承了所有链表的基本操作。 - 接口的角度。
LinkedList
实现了Deque
接口,这表明了即使是链表,也能够实现双端队列的功能,使程序调用者可以将LinkedList
同等视为队列使用。
参考资料