C ++ tiene una herencia múltiple simple, muchos diseños de lenguaje lo prohíben como peligroso. Pero algunos lenguajes como Ruby y PHP usan una sintaxis extraña para hacer lo mismo y llamarlo mixins o rasgos. Muchas veces escuché que los mixins / rasgos son más difíciles de abusar que la simple herencia múltiple.
¿Qué los hace específicamente menos peligrosos? ¿Hay algo que no es posible con mixins / rasgos pero posible con herencia múltiple estilo C ++? ¿Es posible encontrarse con el problema del diamante con ellos?
Esto parece como si estuviéramos usando herencia múltiple, pero solo inventando excusas de que esos son mixins / rasgos para que podamos usarlos.
Respuestas:
Hay una serie de problemas con la herencia múltiple cuando se usa con clases completas, pero todas giran en torno a la ambigüedad .
La ambigüedad se muestra de diferentes maneras:
x
, y el tipo derivado preguntax
, ¿qué obtiene?x
variables tienen tipos incongruentes, podría inferirlo.f
con firmas idénticas y alguien llamaf
, ¿a quién se llama?Y eso ignora cosas como el despacho dinámico, la inferencia de tipos, la coincidencia de patrones y otras cosas sobre las que sé menos y que se vuelven más desafiantes cuando el lenguaje admite la herencia múltiple de clases completas.
Los rasgos o Mix-ins (o interfaces, o ...) son construcciones que limitan específicamente las capacidades de un tipo para que no haya ambigüedad. Raramente poseen algo ellos mismos. Esto permite que la composición de los tipos sea más suave porque no hay dos variables o dos funciones ... hay una variable y una referencia; una función y una firma. El compilador sabe qué hacer.
El otro enfoque común adoptado es obligar al usuario a "construir" (o mezclar) su tipo de uno en uno. En lugar de que las clases base sean socios iguales en el nuevo tipo, agrega un tipo a otro, anulando todo lo que estaba allí (generalmente con sintaxis opcional para renombrar y / o volver a exponer los bits anulados).
Dependiendo del idioma, generalmente se vuelve problemático o imposible combinar implementaciones de funciones y almacenamiento para variables de múltiples clases base y exponerlas en el tipo derivado.
Ocasionalmente, aparecerán variaciones menos severas en función de su idioma, pero generalmente no. El punto completo de los rasgos es romper ese tipo de ambigüedad.
fuente
with
palabra clave allí.