Das offensichtlichste Problem ist die Überschreibung von Funktionen.
Nehmen wir an, Sie haben zwei Klassen A
y B
, die beide eine Methode definieren doSomething
. Nun definieren Sie eine dritte Klasse C
, die sowohl von A
y B
aber Sie überschreiben nicht die doSomething
Methode.
Wenn der Compiler diesen Code erzeugt...
C c = new C();
c.doSomething();
...welche Implementierung der Methode sollte sie verwenden? Ohne weitere Klärung ist es für den Compiler unmöglich, die Mehrdeutigkeit aufzulösen.
Neben dem Overriding ist das andere große Problem bei der Mehrfachvererbung die Anordnung der physischen Objekte im Speicher.
Sprachen wie C++, Java und C# erstellen ein festes adressbasiertes Layout für jede Art von Objekt. Etwa so:
class A:
at offset 0 ... "abc" ... 4 byte int field
at offset 4 ... "xyz" ... 8 byte double field
at offset 12 ... "speak" ... 4 byte function pointer
class B:
at offset 0 ... "foo" ... 2 byte short field
at offset 2 ... 2 bytes of alignment padding
at offset 4 ... "bar" ... 4 byte array pointer
at offset 8 ... "baz" ... 4 byte function pointer
Wenn der Compiler Maschinencode (oder Bytecode) erzeugt, verwendet er diese numerischen Offsets für den Zugriff auf die einzelnen Methoden oder Felder.
Die Mehrfachvererbung macht die Sache sehr kompliziert.
Wenn Klasse C
erbt sowohl von A
y B
muss der Compiler entscheiden, ob er die Daten in AB
Auftrag oder in BA
bestellen.
Stellen Sie sich nun aber vor, Sie rufen Methoden auf einer B
Gegenstand. Ist es wirklich nur ein B
? Oder ist es tatsächlich ein C
Objekt, das polymorph aufgerufen wird, durch seine B
Schnittstelle? Je nach der tatsächlichen Identität des Objekts wird das physische Layout unterschiedlich sein, und es ist unmöglich, den Offset der aufzurufenden Funktion am Aufrufort zu kennen.
Der Weg, mit dieser Art von System umzugehen, besteht darin, den Ansatz des festen Layouts aufzugeben und jedem Objekt zu erlauben, nach seinem Layout gefragt zu werden vor beim Versuch, die Funktionen aufzurufen oder auf ihre Felder zuzugreifen.
Also... lange Rede kurzer Sinn... es ist ein Schmerz im Nacken für Compiler-Autoren zur Unterstützung der Mehrfachvererbung. Wenn also jemand wie Guido van Rossum Python oder Anders Hejlsberg c# entwickelt, wissen sie, dass die Unterstützung von Mehrfachvererbung die Compiler-Implementierungen erheblich komplexer machen wird, und vermutlich sind sie der Meinung, dass der Nutzen die Kosten nicht wert ist.
60 Stimmen
Ich möchte nur erwähnen, dass C++ großartig ist, um Ihnen genug Seil zu geben, um sich selbst aufzuhängen.
1 Stimmen
Eine Alternative zur Mehrfachvererbung, die viele der gleichen Probleme angeht (und, IMHO, auch löst), sind Traits ( iam.unibe.ch/~scg/Forschung/Traits )
54 Stimmen
Ich dachte, C++ gibt Ihnen genug Spielraum, um sich selbst in den Fuß zu schießen.
7 Stimmen
Diese Frage scheint davon auszugehen, dass es ein Problem mit MI im Allgemeinen gibt, während ich viele Sprachen gefunden habe, in denen MI gelegentlich verwendet wird. Es gibt sicherlich Probleme mit der Handhabung von MI in bestimmten Sprachen, aber ich bin mir nicht bewusst, dass MI im Allgemeinen signifikante Probleme hat.