我一直很喜欢在一种语言中支持多重继承的想法。尽管通常是故意放弃的,但所谓的“替换”是接口。接口根本不能涵盖所有相同的多重继承,并且这种限制有时可能会导致产生更多样板代码。
我听说过的唯一基本原因是基类的钻石问题。我就是不能接受。对我来说,它的表现非常糟糕,例如:“嗯,有可能将其弄糟,所以这自然不是一个好主意。” 但是,您可以用编程语言修改任何内容,我的意思是。我只是不能认真对待这一点,至少没有没有更彻底的解释。
仅知道这个问题就占了90%。此外,我想我几年前听说过涉及通用解决方案的问题,该解决方案涉及“信封”算法或类似的东西(有人敲响铃吗?)。
关于钻石问题,我能想到的唯一潜在的真正问题是,如果您正在尝试使用第三方库,并且看不到该库中两个看似无关的类具有共同的基类,那么除了例如,文档是一种简单的语言功能,可能要求您明确声明要创建菱形的意图,然后才能为您实际编译菱形。有了这样的功能,任何钻石的制造要么是故意的,鲁ck的,要么是因为人们没有意识到这一陷阱。
所有人都这么说... 大多数人是否有真正的理由讨厌多重继承,还是仅仅是一堆歇斯底里会造成弊大于利?有没有我在这里看不到的东西?谢谢。
例
汽车扩展了WheeledVehicle,KIASpectra扩展了汽车和电子产品,KIASpectra包含无线电。为什么KIASpectra不包含电子产品?
因为它是电子的。继承vs.组合应该始终是is-a关系vs.has-a关系。
因为它是电子的。上下都有电线,电路板,开关等。
因为它是电子的。如果冬天电池没电了,您的麻烦就好像所有车轮突然丢失一样。
为什么不使用接口?以#3为例。我不想一遍又一遍地写这个,而且我真的不想创建一些奇怪的代理帮助器类来做到这一点:
private void runOrDont()
{
if (this.battery)
{
if (this.battery.working && this.switchedOn)
{
this.run();
return;
}
}
this.dontRun();
}
(我们不会考虑该实现的好坏。)您可以想象如何可能有一些与电子相关的功能与WheeledVehicle中的任何内容都不相关,反之亦然。
我不确定是否要解决该示例,因为那里有解释的空间。您还可以考虑从平面扩展Vehicle和FlyingObject,以及从Bird扩展Animal和FlyingObject,或者从更纯粹的示例方面进行思考。
Traits
-它们的作用类似于具有可选实现的接口,但是有一些限制可以防止出现钻石问题。
KiaSpectra
不是一个 Electronic
; 它具有电子设备,并且可能是电子设备(可能ElectronicCar
会扩展Car
...)