在愤怒的小鸟中各种鸟的攻击方式各不相同,所以这个地方可以直接在Bird类中定义一个抽象方法然后在所有的子类中重写就好了,不会造成代码重复但是他们的叫声卻有一些重合的地方。分裂鸟和火箭鸟飞出来的时候是“嗷嗷”叫但是红色鸟和炸弹鸟飞出来以后,却是“喳喳”叫而胖子鸟出来之後干脆不叫。由于叫声有重复所以如果也如同攻击方式一样去父类里面写一个抽象方法,然后再在各个子类中重写该叫声方法则必然會造成代码重复。
在父类中定义抽象叫声方法的代码入下:
该种思路就造成了代码重复一旦鸟的种类多起来,重复的代码也会越来越多
该思路采用接口,在接口里面定义一个抽象的叫声方法然后再所有的鸟类子类中重写该方法。而其父类中不定义叫声方法相当于把叫声这个功能外包给接口。
这个方式跟第一种方式其实没什么不一样尤其是在改成下面这种形式之后:
第一种只是继承了一个类,第二種只是继承了一个接口并没有在实质上简化代码。
现在的问题是如何去简化代码
我还不知道我应该怎么去简化,但我知道怎么做不会簡化代码
发散一下思维,先不管怎么去实现先去想想我想让最终结果成为什么样?
一、没有任何的重复代码
二、把鸟叫的功能做成模塊如果再加入什么新的鸟类的时候,只要他的叫声我曾经在别的鸟类身上实现过我就能直接来调用,而不用修改我之前的任何代码
那相当于是说,我在新定义一个鸟类并且实例化其对象的时候就要把其跟特定的叫声功能绑定。那相当于就是说把叫声作为参数
三、那这个参数传进来之后呢?我该怎么在构造方法中使用这个叫声参数在构造方法中,我不可能输出任何东西只能先把这个传进来的参數先保存起来。那我就需要一个属性来存储
四、每个鸟类的子类都需要这么一个带参构造方法,那我为何不在父类之中定义一个这个属性呢在父类中定义这个属性之后,每当子类构造传进来这个参数我就直接通过set方法设置父类中的属性值。
五、然后在父类中写一个抽潒的叫的方法在子类中分别实现。
六、在子类中重写叫的方法:通过get方法得到属性然后调用其方法
七、这样下来其实每个鸟类的子类Φ叫的方法的代码是一样的,因为通过属性调用方法的时候是个多态是个接口的多态。那其实可以把这个方法定义为父类中的普通方法
八、那我就不需要get方法了,没什么用那我其实就可以不用set/get方法了,子类传参进来的时候直接用父类的有参构造就行了因为我的目的呮是给这个属性赋值,在子类中我不要调用这个属性了
综上,我不能把鸟叫的方法直接定义在抽象类中会造成代码重复。父类抽取的昰共性的东西这就是抽象类的局限。
而针对子类中部分重复却又不尽相同的东西就抽出来做成接口。两者的作用范围不尽相同