“优先使用对象组合,而不是继承”是面向对象设计的原则之一。
组合也叫“对象持有”,就是在类中定义另一类型的成员,继承会破坏类的独立性,增加系统的复杂性,一般系统的继承层次不超过3层。组合拥有良好的扩展性,支持动态组合,因此优先考虑组合方法。
看一个例子,有这样一个类:
class Eye { public: void Look(void); };
现在希望定义一个Head类,也想实现Look的功能,应该使用组合方法,实现代码重用,即:
class Head { public: Eye _eye; //Eye对象作为Head的一个成员 };
组合是在新类中以原有类的对象作为数据成员,继承是在不改变现有的类的基础上,采用现有类的形式并在其中添加新代码,组合一般用于在新类中使用现有类的功能而不是它的接口的情况,就是新类用户看到的只是为新类所定义的接口。而继承则是用于在新类需要向基类转化的情况(多态),这也是组合和继承使用的最清晰的判断方法。
我们只需让Eye作为Head的一个成员即可,而让Head去继承Eye的特性是没有必要的。
再看一个例子:有A,B,C三个类,其中B继承A,而A使用C的功能(即组合),那么我们可以这些写:
#include <iostream> using namespace std; class C { public: void print_all() { cout << "hello all." << " "; } }; class A { public: virtual void print(){cout << "hello A" << ' ';} void _print() { c.print_all(); } C c; //C的对象c作为A的成员 }; class B:public A { public: void print(){cout << "hello B" << " ";} }; int main(int argc, char const *argv[]) { B b; b.print(); //hello B b._print(); //hello all. return 0; }
在应用域,符合意味着has-a。在实现域,复合意味着根据某物实现出。