Ric*_*ick 6 javascript ruby oop inheritance computer-science
在某些情况下,提倡组合而不是继承.我在Ruby和Javascript社区中看到这种情况越来越多.
作文听起来很像多重继承.我甚至在一些Ruby实现中内部读过,模块组合是IS多重继承,具有较小的语法糖.
这是一回事吗?如果没有,它与多重继承有什么不同?
这取决于您所说的“多重继承”和“组合”是什么意思。如果组合和继承都只是意味着添加到对象响应的消息列表中,那么它们在定义上是相等的。
假设类只是方法的虚拟表,并且语言中的每个对象都由对类和一些数据的引用定义。如果一个对象通过调用与其类关联的方法查找函数来响应消息,并且方法查找函数要么返回该方法(如果该类包含与该消息对应的方法)要么递归调用其超类上的方法查找函数,我们有一种单继承且没有组合的语言。可以通过修改Open Extensible Object Models 的2.2 节中描述的方法查找函数来添加多继承这样的语言,伊恩·皮马塔。基本上,只需添加一个类,该类将方法查找推迟到多个其他类而不是一个。很容易看出可以以完全相同的方式添加混合/特征(我假设这就是您所说的组合)。
但是,如果“组合”是指一个对象具有其他对象作为实例变量,那么有一个很好的理由使用它而不是多重继承:封装。如果可以在父对象上调用实例变量中的对象上的某些方法,它们将毫无意义。
很多人从技术角度谈论多重继承,但我想谈谈设计方面。
在良好的 OOP(面向对象编程)设计中,您不应该使用多重继承。为什么?
1.
就像GRASP 模式所暗示的高内聚模式一样,一个类不应该有太多的责任。
2.
继承锁定您的架构。如果你想改变什么,你必须改变一切。我给你举个例子:想象一些类喜欢car
,truck
,boat
并plane
从类继承motorVehicle
。现在,我添加一个新概念:汽车、卡车、船和飞机也是移动的交通工具。我该怎么办?
motorVehicle
比 a 多movingVehicle
?motorVehicle
和movingVehicle
。我的班级将有两种不同的高度相关的职责,这真的很糟糕。如果我加一辆自行车怎么办!这就是为什么继承应该只用于分解具有相同职责的类的代码!
结论
如果一个类应该只有一个明确的职责,并且您应该只对具有相同职责的类使用继承,那么在正确的 OOP 设计中永远不应该使用多重继承。
我建议你总是使用带有接口的组合来降低你的类之间的耦合。这将为您提供更具可扩展性、可维护性和可测试性的代码!
在前面的例子中,使用组合会导致一些电机类继承自电机接口,一些移动类继承自移动接口,类
car
,truck
, ... 将“使用”电机接口和移动接口。而我们bicycle
将只能“使用”一个移动界面!