9

可能重复:
多重继承的确切问题是什么?

为什么多重继承被认为是邪恶的,而实现多个接口却不是?尤其是当曾经认为接口只是纯粹的抽象类时?

(或多或少)重复 多重继承的确切问题是什么?C#中的多重继承,以及其他一些......

4

4 回答 4

28

多重继承的常见问题是“钻石问题”。

  A
 / \
B   c
 \ /
  D

如果 A 中的一个虚方法由 B 和 C 共同实现,那么你在创建 D 时会得到哪一个?

这不是接口问题的原因是因为接口没有实现,所以如果 A/B/C 都是接口,那么 D 选择如何以任何合适的方式实现 A 方法。

于 2008-12-13T07:09:16.347 回答
13

它被认为是邪恶的,因为它比人们通常预期的更复杂并且引发的问题更多,尤其是在基类不是纯粹抽象的(没有数据成员)的情况下。菱形继承可以使用虚拟继承来解决,其中共享一个公共基础。编译器可以捕获方法签名冲突。使用得当,它可以产生优雅和干燥的解决方案,否则通过接口和组合/委托来实现更加冗长。

C++ 中一个常见的 MI 习惯用法是用于复杂的包装构造函数,其中基构造函数需要使用非平凡的成员对象构造,并且由于需要在成员对象之前构造基对象,因此诀窍是使用 MI(“来自成员的基础”成语。),否则您必须使用工厂和更多步骤来像Java那样进行构造(Java没有用于非接口类的MI)。

不要害怕它并在适当的时候使用它(尽管可能需要一些练习才能找到合适的)。

于 2008-12-13T07:46:33.730 回答
3

MI 与其说是邪恶的,不如说是一个罕见问题的高度复杂的解决方案。在大多数情况下,有更好的方法来完成同样的事情。

于 2008-12-13T07:22:25.337 回答
2

如果 A 实现了一个名为 z 的方法,而 b 实现了一个名为 z 的方法,并且您有:

孩子:a,b

现在,如果我的客户端代码调用 new child().z()。哪个实现被调用?我不认为它是邪恶的,它只是提出了一大堆的粘性点并且提供了很少的价值

于 2008-12-13T07:08:03.183 回答