El problema más obvio es con la anulación de funciones.
Digamos que tiene dos clases A
y B
, las cuales definen un método doSomething
. Ahora define una tercera clase C
, que hereda de ambos A
y B
, pero no anula el doSomething
método.
Cuando el compilador inicia este código ...
C c = new C();
c.doSomething();
... ¿Qué implementación del método debería usar? Sin ninguna otra aclaración, es imposible que el compilador resuelva la ambigüedad.
Además de anular, el otro gran problema con la herencia múltiple es el diseño de los objetos físicos en la memoria.
Lenguajes como C ++ y Java y C # crean un diseño fijo basado en direcciones para cada tipo de objeto. Algo como esto:
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
Cuando el compilador genera código de máquina (o código de bytes), utiliza esos desplazamientos numéricos para acceder a cada método o campo.
La herencia múltiple lo hace muy complicado.
Si la clase C
hereda de ambos A
y B
, el compilador tiene que decidir si desea diseñar los datos en AB
orden o en BA
orden.
Pero ahora imagina que estás llamando métodos a un B
objeto. ¿Es realmente solo un B
? ¿O es realmente un C
objeto que se llama polimórficamente, a través de su B
interfaz? Dependiendo de la identidad real del objeto, el diseño físico será diferente, y es imposible saber el desplazamiento de la función para invocar en el sitio de la llamada.
La forma de manejar este tipo de sistema es deshacerse del enfoque de diseño fijo, permitiendo que cada objeto sea consultado por su diseño antes de intentar invocar las funciones o acceder a sus campos.
Entonces ... larga historia corta ... es un dolor en el cuello para los autores del compilador admitir la herencia múltiple. Entonces, cuando alguien como Guido van Rossum diseña python, o cuando Anders Hejlsberg diseña c #, saben que admitir la herencia múltiple hará que las implementaciones del compilador sean significativamente más complejas, y presumiblemente no creen que el beneficio valga la pena.