第16条:复合优先于继承

来源:互联网 发布:国产美容仪 知乎 编辑:程序博客网 时间:2024/04/30 11:36
这里的继承是实现继承而非接口继承。
与方法调用不同的是,继承打破了封装性:
换句话说,子类依赖于其超类中特定功能的实现细节。超类的实现有可能会随着发型版本的不同而发生改变,如果真的发生了变化,子类可能会遭到破坏,即使他的代码完全没有改变。因此,子类必须跟着超类的更新而改变,除非超类是专门为扩展而设计的,并用具有很好的文档说明。
只有当子类真正是超类的子类型(subtype)时,才适合用继承,也就是是“is-a”关系时。
如果在适合于是用复合的地方是用了继承,则会不必要的暴漏实现细节。这样的到的API会把你限制在原始的实现上,永远限定了类的性能。更为严重的是,由于暴漏了内部细节,客户端就有可能直接访问这些内部细节。这样至少会导致语义上的混淆。例如:Properties,getProperty(String key)就有可能产生与get(Object key) 不同的结果。
对于你正视图扩展的类,他的API有没有缺陷?如果有,你愿意把那些缺陷传播到子类的API中?而符合则允许设计新的API来隐藏这些缺陷。


可以不扩展现有的类,而是在新类中增加一个私有域,他 引用现有类一个实例。这种设计叫做“复合(composition)”,因为现有的类变成新类的一个组件。新类中的每个实例方法都可以调用被包含的现有类实例中对应的方法,并返回他的结果。这被成为转发(forwarding),新类中的方法被成为转发方法(forwarding method)。 
原创粉丝点击