1 鸭子抽象类
class Duck { quack(); swim(); virtual display()=0 };
现在如果让鸭子能够飞
class Duck { quack(); swim(); fly(); virtual display()=0 };
在抽象类中加上fly()将不是一个好的方案,因为在派生类中(各种不同的鸭子),有些鸭子并不可以飞,可以采用覆盖fly()的方法
利用继承来提供Duck的行为,将导致
1)代码在多个子类中重复
2)运行时的行为不容易改变
3)难于扩展,新增行为会改变几乎所有派生类
如果利用接口来实现fly和quack,对于C++而言将是定义Fly和Quack两个抽象类,在需要fly和quack的Duck派生类中继承这两个抽象类
但是这些派生类需要完全实现fly和quack,两个抽象类仅仅是将fly和quack抽象出来,代码无法复用
2 问题分析
使用继承并不能很好的解决问题,鸭子的行为在子类里不断变化,并且让所有子类都拥有这些行为时不恰当的。
Fly和Quack接口似乎解决了这个问题,只有fly和quack的鸭子才会继承这两个接口。但是Java接口不具有实现代码,继承接口无法实现代码复用
设计原则一:找出应用中需要变化之处,把它们独立出来,不和那些不需要变化的代码混在一起
由于鸭子的行为各不相同,所以将行为从抽象类Duck中分离出来,实现Fly和Quack基类,派生出不同的fly和quack类
设计原则二:针对接口编程,而不是针对实现编程
我们希望鸭子的行为有弹性,即鸭子的行为可以动态改变,这就需要针对接口编程
针对接口编程的正真意思是针对基类编程,在Duck类中添加行为基类的指针对象,在Duck派生类中通过该指针调用具体的行为