Frage

Wikipedia auf dem Diamant-Problem:

“... der Diamant Problem ist eine Zweideutigkeit, die, wenn zwei Klassen B und C, vererben A und Klasse D erbt von beiden B und C. Wenn eine Methode in D ruft eine Methode definiert in A (und tut entsteht nicht überschreiben die Methode), und B und C haben außer Kraft gesetzt, dass Verfahren anders, dann, von der Klasse tut es erbte: B oder C "

So die Diamant sieht wie folgt aus:

  A
 / \
B   C
 \ /
  D

Meine Frage ist, was passiert, wenn es keine solche Klasse A ist, aber auch hier B und C erklären die gleiche Methode, sagen foo (). Ist das nicht das gleiche Problem? Warum ist es dann Diamant Problem genannt?

Beispiel:

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

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

class D extends B, C {
}

new D().foo();
War es hilfreich?

Lösung

Es ist nicht das gleiche Problem.

Im ursprünglichen Problem kann die überschriebene Methode von A. In Ihrem Problem genannt werden dies nicht der Fall sein kann, weil es nicht existiert.

In dem Diamanten Problem, geschieht der Zusammenstoß, wenn die Klasse A die Methode Foo aufruft. Normalerweise ist dies kein Problem. Aber in der Klasse D kann man nie wissen, welche Instanz von Foo genannt zu werden braucht:

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

Ihr Problem gibt es keine gemeinsamen Vorfahren, der die Methode aufrufen können. Auf Klasse D gibt es zwei Arten von Foo Sie wählen kann, aber zumindest wissen Sie, dass es zwei sind. Und Sie können eine Wahl zwischen den beiden machen.

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

Aber, wie immer, Sie brauchen keine Mehrfachvererbung. Sie können aggegration und Schnittstellen verwenden, um all diese Probleme zu lösen.

Andere Tipps

In der Diamant-Problem, Klasse D implizit die virtuelle Methode aus der Klasse A. erbt es nennen würde Klasse D nennen:

A::foo()

Wenn beide Klassen B und C diese Methode überschreiben, dann kommt das Problem der die tatsächlich aufgerufen wird.

In Ihrem zweites Beispiel ist dies jedoch nicht der Fall, da Klasse D explizit müßten Zustand, der genannt wurde:

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

So werden die Probleme nicht wirklich gleich sind. In dem Diamanten Problem verweisen Sie nicht die abgeleiteten Klassen, aber ihre Basisklasse, daher die Zweideutigkeit.

Das ist, wie ich es verstehe, sowieso.

Beachten Sie, dass ich von einem C ++ Hintergrund komme.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top