参见英文答案 > Prefer composition over inheritance? 32个
在设计模式中,我一次又一次地听到这种有利于构成的构成.引用的一些原因是
1)Inheritance is strongly coupled where as composition is loosely coupled
2) Inheritance is compile time determined where as composition is run-time
3)Inheritance breaks encapsulation where as composition does not
4) anything else I am not aware of
对于像我这样的初学者来说,通过插图来理解遗传和构图在上述方面的不同之处将会很棒.我已经阅读了各种谈论它们的SO链接,但是通过这些关键点的示例对Java初学者来说非常有用.
我认为清楚地理解差异非常重要,而不仅仅是记住要点.
解决方法:
对于初学者来说这个问题很好,我想我应该首先提醒读者什么是继承和组合,然后再继续解释什么是继承对继承的影响.
继承的利弊:
好处:
>动态绑定和多态性的主要好处之一是
它们可以帮助使代码更容易更改.
>新实现很容易,因为大部分都是继承的.这很容易
修改或扩展正在重用的实现.
缺点:
>打破封装,因为它将子类暴露给实现
超级的细节.
>白盒重用,因为超类的内部细节经常出现
对子类可见.
>如果实现了子类,则可能必须更改子类
超类更改.从超类继承的实现可以
不能在运行时更改.
关于这个问题:
Inheritance is strongly coupled where as composition is loosely coupled
继承会带给你紧耦合,只需对基类进行一次更改就可以打破很多子类.
但是何时使用以及如何检测我们需要继承或组合?
仅在满足以下所有条件时使用继承(Coad规则):
>子类表达是一种特殊的,而不是由a扮演的角色.
>子类的实例永远不需要成为另一个类的对象.
>子类扩展而不是覆盖或取消其职责
它的超级.
>子类不会扩展仅仅是a的功能
实用班.
>对于实际问题域中的类,子类专门化
角色,交易或设备.
Inheritance is compile time determined where as composition is run-time
编译时,您的基类代码将添加到每个子类.
Inheritance breaks encapsulation where as composition does not
是.现在你看到了继承的缺点.
底线是:
确保继承模型是is-a关系
我的主要指导思想是只有当子类是超类时才应该使用继承.在上面的例子中,Apple可能是一个Fruit,所以我倾向于使用继承.
当你认为你有一个is-a关系时,问一个自己的一个重要问题是,这是一个关系在整个应用程序的整个生命周期中是不变的,幸运的是,代码的生命周期.例如,您可能认为Employee是一个Person,而真正的Employee代表一个Person扮演部分时间的角色.如果这个人失业怎么办?如果该人既是员工又是主管怎么办?这种无常的关系通常应该用构图来建模.
不要仅仅为了获得代码重用而使用继承
如果您真正想要的只是重用代码并且看不到任何关系,请使用合成.
不要仅仅为了获得多态性而使用继承
如果您真正想要的只是多态,但没有自然的关系,请使用带接口的组合.
赞成组合Over Inheritance