维基百科上的金刚石问题:

” ...金刚石的问题是,当出现两个类B和C从A继承歧义,和类d来自B和C继承如果d的方法调用A中所定义的方法(和不覆盖的方法),和B和C已重写该方法不同,那么从哪一类它继承:B或C“

因此,金刚石看起来像这样:

  A
 / \
B   C
 \ /
  D

我的问题是,如果不存在这样的类A,但再次B和C声明相同的方法会发生什么情况,说FOO()。这难道不是同样的问题?为什么当时称为钻石的问题?

示例:

class B {
    public void foo() {...}
}

class C {
    public void foo() {...}
}

class D extends B, C {
}

new D().foo();
有帮助吗?

解决方案

它不是同样的问题。

在原始的问题,覆盖方法可以从A.称为在您的问题,因为它不存在,这不可能是如此。

在金刚石问题,冲突发生,如果类A调用方法FOO。通常,这是没有问题的。但在d类,你可以永远不知道它的Foo实例需要调用:

         +--------+
         |   A    |
         | Foo    |
         | Bar    |
         +--------+
            /  \
           /    \
          /      \
+--------+        +--------+
|   B    |        |   C    |
| Foo    |        | Foo    |
+--------+        +--------+
          \      /
           \    /
            \  /
         +--------+
         |   D    |
         |        |
         +--------+

在您的问题,没有任何共同的祖先,可以调用该方法。在d类有富的两种口味,你可以从选择,但至少你知道有两个。你可以在两者之间作出选择。

+--------+        +--------+
|   B    |        |   C    |
| Foo    |        | Foo    |
+--------+        +--------+
          \      /
           \    /
            \  /
         +--------+
         |   D    |
         |        |
         +--------+

不过,一如既往,你并不需要多重继承。您可以使用aggegration和接口来解决所有这些问题。

其他提示

在金刚石问题,类d隐式地继承类A的虚拟方法调用它,类d将调用:

A::foo()

如果这两个类者B,C覆盖此方法,则问题就来了,其中实际被调用。

在您的但是第二示例中,不是这种情况下,d类需要显式 这是被称为状态:

B::foo()
C::foo()

因此,问题实际上不是相同的。在金刚石问题您没有引用派生类,但它们的基类,因此不明确性。

这就是我所理解吧,反正。

请注意,我是从一个C ++背景的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top