本文应该为您提供一个完整的答案: 设计模式中的设计原则:组合与继承
我在这里引用Erich Gamma的直接回答:
十年后我仍然认为这是真的.继承是改变行为的一种很酷的方式.但我们知道它很脆弱,因为子类可以轻松地对其覆盖的方法被调用的上下文进行假设.基类和子类之间存在紧密耦合,因为我将调用插入的子类代码的隐式上下文.组合物具有更好的性质.通过将一些较小的东西插入更大的东西来减少耦合,而较大的对象只是将较小的对象调回来.从API的角度来看,定义一个方法可以被覆盖是一个比定义一个方法可以被调用更强的承诺.
在子类中,您可以在调用覆盖的方法时对超类的内部状态进行假设.当你插入某些行为时,它会更简单.这就是你应该支持作曲的原因.一个常见的误解是组合根本不使用继承.组合使用继承,但通常只是实现一个小接口,而不是从大类继承.Java监听器习语是一个很好的组合示例.使用侦听器,您可以实现侦听器接口或从所谓的适配器继承.例如,您创建一个侦听器对象并使用Button小部件注册它.没有必要将Button子类化以对事件做出反应.