继承(inheritance) 是实现代码重用的有力手段,但它并非永远是完成这项工作的最佳工具.
在包的内部使用继承是非常安全的.然而,对于普通的具体类进行跨越包边界的继承,则是非常危险的.
与方法调用不同的是,继承打破了封装性.
- 子类依赖于其超类中特定功能的实现细节.
- 超类在后续的版本中可以获得新的方法.
避免上述问题: 不用扩展现有的类,而是在新的类中新增一个私有域,它引用现有类的一个实例. 这种设计被称为"复合"(composition)
这样得到的类会非常稳固,它不依赖于现有类的实现细节,即使现有的类添加了新的方法,也不会影响新的类.
只有当子类真正是超类的子类型时, 才适合继承.
也就是对于两个类A和B, 只有当两者之间确实存在"is-a"关系的时候,类B才应该扩展A.
简而言之, 继承的功能非常强大,但是也存在诸多问题,因为它违背了封装原则.只有当子类和超类之间确实存在子类型关系时,使用继承才是恰当的. 即便如此, 如果子类和超类处在不同的包中, 并且超类并不是为了继承而设计的, 那么继承将会导致脆弱性. 为了避免这种脆弱性, 可以用复合和转发机制来代替继承,尤其是当存在适当的接口可以实现包装类的时候. 包装类不仅比子类更加健壮, 而且功能也更加强大.