Usted está pidiendo "¿Por qué Java no soporta herencia múltiple de implementación?"
Esto se discute en los Tutoriales de Java, Multiple Inheritance of State, Implementation, and Type, pero quería dar un ejemplo específico de los problemas de herencia múltiple de implementación (así como una nueva solución de características de idioma al final).
Imagine dos interfaces (en nuestra versión propuesta de Java que permite cuerpos de métodos de interfaz) que definen un método con el mismo nombre.
public interface FaceOne {
public void method() {
System.out.println("FaceOne Version");
}
}
public interface FaceTwo {
public void method() {
System.out.println("FaceTwo Version");
}
}
Y una clase implementa ambas interfaces, pero no anula el método.
public class Inheriter implements FaceOne, FaceTwo {
}
Cuando llamo Inheriter.method()
, que funciona ya que la clase hereda el método de sus ancestros, surge el problema: lo hace la impresión de salida "Versión FaceOne" o "Versión FaceTwo"?
Además, si la clase debía sobrescribir el método, pero también quería llamar a la versión de su antecesor utilizando super
, el compilador volvería a tener problemas para elegir entre una versión del método.
Es por eso que Java no admite herencia múltiple de implementación.
Como acotación al margen, creo que una manera elegante de implementar esto en el lenguaje sería la siguiente:
siguen obligando a las clases que implementan para reemplazar los métodos de la interfaz ancestro. Esto resuelve el primer problema de un método no invalidado.
Luego, use una notación similar a that of accessing an enclosing instance for an inner class para acceder a una interfaz ancestro específica con super
. La clase Inheriter tendría entonces múltiples opciones:
No llamar super.method()
, sino que sólo se utilice la aplicación recién definida.
Utilice FaceOne.super.method()
para realizar la salida de implementación heredada predeterminada "FaceOne Version".
Utilice FaceTwo.super.method()
para realizar la salida de implementación heredada predeterminada "Versión de FaceTwo".
Use una combinación de los anteriores:
Una aplicación podría ser:
@Override
public void method() {
FaceOne.super.method();
FaceTwo.super.method();
System.out.println("Inheriter Version");
}
Salida de:
FaceOne Versión
FaceTwo Versión
Inheriter Versión
Editar: De acuerdo con this question esto es al parecer exactamente cómo implementaciones por defecto se estructuran en Java 8.
porque de lo contrario se habría conseguido el lío de regular (C++ similares) múltiple herencia, que generalmente es complejación redundante. – amit
me preguntaron esto en una entrevista, ¿podría explicar esto? –
Las interfaces son * no * "herencia múltiple". La herencia múltiple es fea, las interfaces son hermosas;) Y las interfaces no * se reemplazan *, están "implementadas". Para comprender las "interfaces" de Java, debe comprender el "polimorfismo OO". Una interfaz Java es un CONTRATO que una clase implementadora debe HONRAR. Una interfaz Java es "especificación"; una clase implementadora proporciona el "comportamiento" real. – paulsm4