可能重复:
多重继承的确切问题是什么?
为什么多重继承被认为是邪恶的,而实现多个接口却不是?尤其是当曾经认为接口只是纯粹的抽象类时?
(或多或少)重复 多重继承的确切问题是什么?,C#中的多重继承,以及其他一些......
可能重复:
多重继承的确切问题是什么?
为什么多重继承被认为是邪恶的,而实现多个接口却不是?尤其是当曾经认为接口只是纯粹的抽象类时?
(或多或少)重复 多重继承的确切问题是什么?,C#中的多重继承,以及其他一些......
多重继承的常见问题是“钻石问题”。
A
/ \
B c
\ /
D
如果 A 中的一个虚方法由 B 和 C 共同实现,那么你在创建 D 时会得到哪一个?
这不是接口问题的原因是因为接口没有实现,所以如果 A/B/C 都是接口,那么 D 选择如何以任何合适的方式实现 A 方法。
它被认为是邪恶的,因为它比人们通常预期的更复杂并且引发的问题更多,尤其是在基类不是纯粹抽象的(没有数据成员)的情况下。菱形继承可以使用虚拟继承来解决,其中共享一个公共基础。编译器可以捕获方法签名冲突。使用得当,它可以产生优雅和干燥的解决方案,否则通过接口和组合/委托来实现更加冗长。
C++ 中一个常见的 MI 习惯用法是用于复杂的包装构造函数,其中基构造函数需要使用非平凡的成员对象构造,并且由于需要在成员对象之前构造基对象,因此诀窍是使用 MI(“来自成员的基础”成语。),否则您必须使用工厂和更多步骤来像Java那样进行构造(Java没有用于非接口类的MI)。
不要害怕它并在适当的时候使用它(尽管可能需要一些练习才能找到合适的)。
MI 与其说是邪恶的,不如说是一个罕见问题的高度复杂的解决方案。在大多数情况下,有更好的方法来完成同样的事情。
如果 A 实现了一个名为 z 的方法,而 b 实现了一个名为 z 的方法,并且您有:
孩子:a,b
现在,如果我的客户端代码调用 new child().z()。哪个实现被调用?我不认为它是邪恶的,它只是提出了一大堆的粘性点并且提供了很少的价值