Il problema più ovvio è con l'override della funzione.
Supponiamo di avere due classi Ae B, entrambe definiscono un metodo doSomething. Ora definisci una terza classe C, che eredita da Ae B, ma non sovrascrivi il doSomethingmetodo.
Quando il compilatore esegue il seed di questo codice ...
C c = new C();
c.doSomething();
... quale implementazione del metodo dovrebbe utilizzare? Senza ulteriori chiarimenti, è impossibile per il compilatore risolvere l'ambiguità.
Oltre all'override, l'altro grosso problema con l'ereditarietà multipla è il layout degli oggetti fisici in memoria.
Linguaggi come C ++ e Java e C # creano un layout basato su indirizzi fissi per ogni tipo di oggetto. Qualcosa come questo:
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
Quando il compilatore genera codice macchina (o bytecode), utilizza quegli offset numerici per accedere a ciascun metodo o campo.
L'ereditarietà multipla lo rende molto complicato.
Se la classe Ceredita da Ae B, il compilatore deve decidere se disporre i dati in ABordine o in BAordine.
Ma ora immagina di chiamare metodi su un Boggetto. È davvero solo un B? O è effettivamente un Coggetto chiamato polimorficamente, attraverso la sua Binterfaccia? A seconda dell'identità effettiva dell'oggetto, il layout fisico sarà diverso ed è impossibile conoscere l'offset della funzione da richiamare nel sito di chiamata.
Il modo per gestire questo tipo di sistema è abbandonare l'approccio del layout fisso, consentendo a ogni oggetto di essere interrogato per il suo layout prima di tentare di invocare le funzioni o accedere ai suoi campi.
Quindi ... per farla breve ... è una seccatura per gli autori di compilatori supportare l'ereditarietà multipla. Quindi, quando qualcuno come Guido van Rossum progetta python, o quando Anders Hejlsberg progetta c #, sa che supportare l'ereditarietà multipla renderà le implementazioni del compilatore significativamente più complesse e presumibilmente non pensano che il vantaggio valga il costo.