继承和委托是设计模式实现的两大机制,也是设计模式的精髓。
业界应用最为广泛的两大平台:SUN公司的JDK和Microsoft公司的MFC都充分利用了继承和委托机制,为代码的重用和扩展提供了非常好的支持。 但是JDK侧重于通过委托机制提供扩展点,MFC侧重通过继承机制提供扩展点,从使用上来看基于JDK的开发远远比基于MFC的开发容易, 扩展更灵活,这很大程度上得益于JDK中普遍使用的委托机制。
要了解继承和委托的区别,先来看一个形象的例子:
比如我要杀一个人,我就有两种办法:继承和委托。
我如果是采用继承的话,就是要习得一身的好功夫,要习得一身好武功就得拜师(一日为师终生为父), 把父亲的功夫变成自己的,自己学会了,自己亲自杀了仇人。
如果采用委托的话,就是雇佣一个杀手,让杀手帮自己杀了仇人,自己不动手。
继承机制是通过扩展一个已有的对象的实现来获得新功能的机制。 委托机制是将类的一部分功能委托给另一个接口或另一个类来实现的机制。
继承机制是通过扩展一个已有的对象的实现来获得新功能,基类明显的捕获共同的属性和方法, 而派生类通过增加新的属性和方法来扩展基类,因此派生类依赖于基类的实现。
继承机制的优点:
新的实现较为容易,因为基类的大部分特性通过继承自动进入派生类
继承机制的缺点:
继承破坏了封装性,因为继承将基类的实现细节暴露给了派生类,如果基类的实现发生了改变,那么派生类也不得不发生改变。
从基类继承来的实现是静态的,不可能在运行时发生改变,因此没有足够的灵活性。
委托机制是将已有对象纳入到新的对象中,使之成为新对象的一部分,因此新对象可以使用已有对象的功能。
委托机制的优点有:
这种复用所需的依赖较少
这种复用是黑箱复用,因为成份对象的内部细节是新对象所看不见的
这种复用是动态的,新对象可以在运行时动态引入与成份对象类型相同的对象。
委托机制的缺点: 需要管理的对象较多。
从他们的优缺点可以看出委托机制优于继承机制,另外从他们的类图可以看出,委托是一维的,单层结构,结构简单; 继承是多维的,多层结构,结构比较复杂。所以在进行设计的时候应该优先考虑使用委托机制实现。
继承代表一般化/特殊化关系,其中基类代表一般,派生类代表特殊,派生类将基类特殊化。一般只有当以下条件同时满足时才能够使用继承:
派生类是基类的一个特殊种类,而不是基类的一部分,也就是要区分is a和has a的不同
只有在分类学角度上有意义时才可以使用继承
委托机制是代表关联关系,只要满足这种关系的够可以使用委托机制实现,他不像继承机制那样有很多限制,引入委托机制的目的是为了是软件设计更为灵活。