Siempre me ha gustado la idea de tener una herencia múltiple admitida en un idioma. La mayoría de las veces, aunque intencionalmente se ha perdido, y la supuesta "sustitución" son las interfaces. Las interfaces simplemente no cubren todo el mismo terreno que la herencia múltiple, y esta restricción puede llevar ocasionalmente a más código repetitivo.
La única razón básica que he escuchado para esto es el problema del diamante con clases básicas. Simplemente no puedo aceptar eso. Para mí, se desprende muchísimo como: "Bueno, es posible arruinarlo, por lo que es automáticamente una mala idea". Sin embargo, puedes arruinar cualquier cosa en un lenguaje de programación, y quiero decir cualquier cosa. Simplemente no puedo tomar esto en serio, al menos no sin una explicación más detallada.
Ser consciente de este problema es el 90% de la batalla. Además, creo que hace años escuché algo sobre una solución de propósito general que involucraba un algoritmo de "envolvente" o algo así (¿esto suena, alguien?).
Con respecto al problema de los diamantes, el único problema potencialmente genuino que se me ocurre es si está intentando usar una biblioteca de terceros y no puede ver que dos clases aparentemente no relacionadas en esa biblioteca tienen una clase base común, pero además de la documentación, una característica de lenguaje simple podría, digamos, requerir que declare específicamente su intención de crear un diamante antes de que compile uno para usted. Con tal característica, cualquier creación de un diamante es intencional, imprudente o porque uno no es consciente de este escollo.
Para que todo se diga ... ¿Existe alguna razón real por la cual la mayoría de las personas odian la herencia múltiple o es solo un montón de histeria que causa más daño que bien? ¿Hay algo que no estoy viendo aquí? Gracias.
Ejemplo
Coche extiende WheeledVehicle, KIASpectra extiende Coche y Electrónica, KIASpectra contiene Radio. ¿Por qué KIASpectra no contiene electrónica?
-
Porque es un electrónico. La herencia frente a la composición siempre debe ser una relación is-a vs una relación has-a.
-
Porque es un electrónico. Hay cables, tableros de circuitos, interruptores, etc., todos arriba y abajo de esa cosa.
-
Porque es un electrónico. Si su batería se agota en el invierno, tendrá tantos problemas como si todas sus ruedas desaparecieran repentinamente.
¿Por qué no usar interfaces? Tome # 3, por ejemplo. No quiero escribir esto una y otra vez, y realmente no quiero crear una clase de proxy proxy extraña para hacer esto tampoco:
private void runOrDont()
{
if (this.battery)
{
if (this.battery.working && this.switchedOn)
{
this.run();
return;
}
}
this.dontRun();
}
(No nos estamos preguntando si esa implementación es buena o mala). Puedes imaginarte cómo puede haber varias de estas funciones asociadas con la electrónica que no están relacionadas con nada en WheeledVehicle, y viceversa.
No estaba seguro de establecer o no ese ejemplo, ya que allí hay espacio para la interpretación. También puedes pensar en términos de Vehículo de extensión de avión y Objeto de vuelo y Objeto de ave y Pájaro y Objeto de vuelo volador, o en términos de un ejemplo mucho más puro.