Siempre me ha gustado la idea de tener herencia múltiple compatible en un idioma. La mayoría de las veces, aunque se olvida intencionalmente, y el supuesto "reemplazo" son las interfaces. Las interfaces simplemente no cubren el mismo terreno que la herencia múltiple, y esta restricción ocasionalmente puede conducir a más código repetitivo.
La única razón básica que he escuchado para esto es el problema del diamante con las clases base. Simplemente no puedo aceptar eso. Para mí, parece mucho, "Bueno, es posible arruinarlo, así que automáticamente es 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 exhaustiva.
Solo estar al tanto de este problema es el 90% de la batalla. Además, creo que escuché algo hace años sobre una solución de propósito general que involucra un algoritmo de "sobre" o algo así (¿esto suena una campana, alguien?).
Con respecto al problema del diamante, el único problema potencialmente genuino en el que puedo pensar es si está tratando de 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 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 realmente compile uno para usted. Con tal característica, cualquier creación de un diamante es intencional, imprudente o porque uno no es consciente de esta trampa.
Dicho todo esto ... ¿Hay alguna razón real por la que la mayoría de las personas odie 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
El automóvil extiende el vehículo con ruedas, KIASpectra extiende el automóvil y electrónico, KIASpectra contiene radio. ¿Por qué KIASpectra no contiene Electronic?
Porque es un electrónico. La herencia versus la composición siempre debe ser una relación es-una relación versus una relación tiene-tiene.
Porque es un electrónico. Hay cables, tableros de circuitos, interruptores, etc. arriba y abajo de esa cosa.
Porque es un electrónico. Si su batería se agota en el invierno, está en tantos problemas como si todas sus ruedas desaparecieran repentinamente.
¿Por qué no usar interfaces? Tome el n. ° 3, por ejemplo. No quiero escribir esto una y otra vez, y realmente tampoco quiero crear una extraña clase de ayuda proxy para hacer esto:
private void runOrDont()
{
if (this.battery)
{
if (this.battery.working && this.switchedOn)
{
this.run();
return;
}
}
this.dontRun();
}
(No estamos analizando si esa implementación es buena o mala). Puede imaginar cómo puede haber varias de estas funciones asociadas con Electronic que no están relacionadas con nada en WheeledVehicle, y viceversa.
No estaba seguro de establecer ese ejemplo o no, ya que hay espacio para la interpretación allí. También se podría pensar en términos de Plano extendiendo Vehículo y FlyingObject y Bird extendiendo Animal y FlyingObject, o en términos de un ejemplo mucho más puro.
Traits
: actúan como interfaces con implementación opcional, pero tienen algunas restricciones que ayudan a evitar que surjan problemas como el problema del diamante.
KiaSpectra
no es una Electronic
; que tiene Electrónica, y puede ser una ElectronicCar
(lo que extendería Car
...)