继承和组合
- 继承是一种 is- a 的关系, 组合是一种 has-a 的关系
- public继承就是一种 is-a 的关系。 也就是说每一个派生类对象都是一个基类的对象
- Date和Time就是一种组合 has-a 的关系, Date组合了Time, 每一个Date对象中都有一个Time对象
对于继承的分析:
在继承方式中, 基类的内部细节对子类可见。而且基类的改变,对派生类的影响很大,派生类和基类间的依赖关系很强,耦合度很高
对于组合的分析:
对象组合是继承之外的另一种复用的选择。因为对象的内部细节是不可见的。组合类之间没有很强的依赖关系,耦合度很低。优先使用对象组合可以保持每个类被更好的封装
继承的样例:
class Time
{};
class Date : public Time
{};
组合的样例:
class Time
{};
class Date
{
Time _t;
}
继承和组合都是很好的复用。 但是实际当中使用的最多的是组合。
原因:
在工程中,我们注重的就是 高类聚,低耦合。
高类聚就是有紧密关系的就尽量放在一起。低耦合普通的来讲就是没有关系的话,耦合度越高关系越紧密,但是没有关系的话就尽量不需要放在一起。类聚度越高越好,耦合度越低越好。
继承和组合中, 继承的耦合度更高一些,因为子类继承了父类的成员变量或者成员函数,所以继承的耦合度较组合来说就更高一些。另外,继承已经稍微破坏了封装性,已经使父类的成员函数或者成员变量可以被继承。
而在组合中,它们的关系是相互独立的,唯一的关系就是Time是Date类的一个成员。
综上所述, 尽量使用的是组合,而不要使用继承。
has-a 和 is-a
但是如何去区分它们呢?什么时候用继承,什么时候用组合呢??
- 如果符合 is-a 的关系, 使用继承
- 如果符合has-a的关系, 使用组合
- 如果两者的关系都能说通的话, 优先使用组合
例如:
头和眼睛的关系, 头上有眼睛, 所以用has-a的关系更加恰当,而不能说眼睛是头
车和公交车的关系, 公交车是车, 当然还可以说车有公交车,所以has-a和is-a都符合,所以优先使用has-a关系