抽象类和接口的选择

抽象类和接口的选择原则

上次的文章讲述了接口的带来的好处之后,我说会继续写一写如何在接口和抽象类之间选择,由于清明假期以及我最近一直在看AQS的实现并且还要上课,所以这篇文章推迟了很久,由于今天早上没课,终于狠下心起早床写完这篇。下面就直接进入正题。

其实接口和抽象类的选择原理还是有点难度的,工作了很多年的老码农也不敢说一定能够理解,因为涉及到面向对象,要能够正确理解接口和抽象类的选择势必要能够理解面向对象,我很早就说了面向对象不是一种技术而是一种思想,是一种编码的方式,大家不要误解面向对象,总这么说显得有点空洞,我将举一个例子来帮助大家理解,这个例子也是我在csdn上看到的,我觉得写的很好,也很有代表性。

假设我们在一家车企工作,你在公司的技术部门,公司肯定有销售部门,销售车时肯定是要展示一些参数突出车子的优点的。假设销售部门提出一个需求,要求展示车子的动力参数,于是你屁颠屁颠的开始写代码。你可能写了一个抽象Motor类,如下:

image.png

因为科技还没有很发达,还在使用燃油发动机,于是你写了一个燃油发动机类去继承Motor,然后交付了1.0版本的APP,使用的很流畅,你暗暗自喜,觉得自己的代码优雅的像诗一样。

随着时间的推移,科技进步了,出现了光发动机和电发动机,由于电池充电速度是用户很在意的一个参数,而光的强度太弱时光发动机又不能工作,于是返回当前环境的光强也是一个很重要的参数,于是你又分别写了对应的类,同样去继承Motor,加入了获取光强和充电时间的代码,如下:

image.png

image.png

依然是万事大吉,完美使用无bug。就在这个时候车企造出了光电混合发动机,依然叫你展示车的动力参数,但是这个时候你懵了,光电混合发动机这个类到底应该继承哪个基类呢。

很显然光电发动机不能继承Motor,这样做会导致使用instanceOf操作符时得到的结果是该发动机既不属于光发动机也不属于电发动机,但是很显然,现实的情况是光电发动机应该应该同时属于光发动机和电发动机。接着你又想让光电混合发动机继承光发动机和电发动机中的任何一个(因为JAVA不允许使用多重继承,所以只能继承一个),但是这样做之后在使用instanceOf操作符时得到的结果是光电混合发动机只属于光发动机或者电发动机,这个结果显然也是不够合理的,于是你崩溃了,你不得不重构代码,于是你将代码的继承结构改成了如下结构

image.png

电发动机

image.png

光发动机

现在光电混合发动机就很好描述了

image.png

多重实现光发动机接口和电发动机接口就完事了,于是交付软件,这个APP又可以正常跑了,你真是太棒了。

通过这个例子简易的描述了接口和抽象类到底应该怎么选择,在设计一个类的时候,如果要将该类设计成为基类,则考虑该类中有没有属性或者成员方法,如果没有就设计成一个接口,如果有就设计成一个抽象类,如果实在不清楚如何选择,那么则直接设计成接口。

你可能感兴趣的