2008-12-13 14 views

Antwort

27

Das häufige Problem mit Mehrfachvererbung ist das "Diamant-Problem".

A 
/\ 
B c 
\/
    D 

Wenn eine virtuelle Methode in A von B und C implementiert wird, welche erhalten Sie, wenn Sie D erstellen?

Der Grund, dass dies kein Problem mit Schnittstellen ist, liegt daran, dass Schnittstellen keine Implementierungen haben. Wenn also A/B/C alle Schnittstellen sind, dann entscheidet D, wie die A-Methoden in welcher Weise implementiert werden.

+2

Es ist kein Problem, wenn Sie möchten, dass D ambiguiert. –

2

Wie Sie vereinbaren, wenn A eine Methode namens z und b implementiert implementiert eine Methode namens z und Sie haben:

Kind: a, b

jetzt, wenn mein Client-Code neue Kind(). Z() aufruft. Welche Implementierung wird aufgerufen? Ich denke nicht, dass es so sehr ist, dass es sein Übel, es wirft nur eine ganze Reihe von klebrigen Punkten und bietet wenig Wert

+0

Dieses Problem kann leicht gelöst werden, wenn der Compiler das Überschreiben der z-Methode in der untergeordneten Klasse erfordert. Dasselbe Problem tritt auch in den Sprachen auf, in denen die Vererbung mehrerer Schnittstellen zulässig ist, wenn Sie über zwei Schnittstellen mit einer Methode mit demselben Namen, aber unterschiedlicher Signatur verfügen. – hariseldon78

3

MI ist nicht so übel wie eine hochkomplexe Lösung für ein seltenes Problem. In den meisten Fällen gibt es einen besseren Weg, um das Gleiche zu tun.

13

Es wird als böse empfunden, weil es nur komplexer ist und mehr Probleme verursacht, als die Leute normalerweise erwarten, insbesondere wenn die Basisklassen nicht rein abstrakt sind (keine Datenmitglieder). Die Diamantvererbung kann mithilfe der virtuellen Vererbung gelöst werden, wobei eine gemeinsame Basis gemeinsam genutzt wird. Und Compiler können Methodensignaturkollisionen abfangen. Gut verwendet, kann es elegante und DRY-Lösungen erzeugen, die ansonsten über Schnittstelle und Kompositionen/Delegationen ausführlicher zu implementieren sind. Ein gemeinsames MI-Idiom in C++ ist für komplexe Wrapper-Konstruktoren, bei denen der Basiskonstruktor mit nicht-trivialen Member-Objekten konstruiert werden muss, und da Basisobjekte vor Member-Objekten konstruiert werden müssen, besteht der Trick darin, MI zu verwenden. Basis von Member "idiom.", ansonsten muss man eine Factory verwenden und weitere Schritte, um die Konstruktion zu machen, wie Java es tut (Java hat keine MI für Nicht-Interface-Klassen).

Haben Sie keine Angst davor und verwenden Sie es, wenn es angemessen ist (obwohl es einige Übung brauchen könnte, um eine gute Passform zu finden).

Verwandte Themen