继承是一种白箱复用,父类的内部细节对子类可见。
对象组合彼此不知道对方内部细节,成为黑箱复用。
继承的优缺点:
(若在逻辑上B是A的一种,则允许B继承A的功能和属性)
1) 子类可以直接重定义父类的操作。
2) 编译时刻决定了,无法在运行期间更改。
3) 子类要知道父类的实现细节,这样就部分破坏了封装性。子类和父类依赖过于紧密,父类的某些变化必然导致子类的变化。开发过程中遇到过类似的问题。这种依赖,限制了灵活性以及复用性。
组合(通过获得对象的引用而在运行时刻动态的定义)的优缺点:
(若在逻辑上A是B的一部分,则不则不允许B从A派生,而是要用A和其它部分组合成B)
1) 对象间通过接口彼此交互。
2) 对象只能通过接口访问,不要也不能知道对方细节,这样不会破坏封装性。
3) 运行时刻可以使用另外一个对象替换这个对象,提高了灵活性。
4) 对象的实现基于接口编写,所以实现上存在较少的依赖关系。
5) 优先使用组合有助于保持每个类被封装,并被集中在单个任务上,提高整体内聚性。类和类的层次都维持一个较小的规模,
6) 基于对象组合的设计会有更多的对象(而又较少的类),且系统的行为依赖于对象间的关系而不是定义在某个类的内部。
理想的情况下,应该通过组合原有构件实现新的功能,而不是创建新的构件。
面向对象设计的第二个原则:优先使用对象组合,而不是类继承。
C++编程序思想:在决定使用继承还是组合时,问问自己是不是需要向上类型转换到基类。如果不需要,就用组合而不用继承。这样可以减少多重继承的可能。如果我们选择继承,用户会认为他们被假设向上类型转换。