Una nueva característica que viene en JDK 8 le permite agregar a una interfaz existente mientras conserva la compatibilidad binaria.
La sintaxis es como
public interface SomeInterface() {
void existingInterface();
void newInterface() default SomeClass.defaultImplementation;
}
De esta manera, para todas las implementaciones existentes de SomeInterface
cuando se actualizan a esta nueva versión, no todas tienen errores de compilación repentinamente newInterface()
.
Si bien esto es bueno, ¿qué sucede cuando implementa dos interfaces que han agregado un nuevo método predeterminado que no implementó? Dejame explicarte con un ejemplo.
public interface Attendance {
boolean present() default DefaultAttendance.present;
}
public interface Timeline {
boolean present() default DefaultTimeline.present;
}
public class TimeTravelingStudent implements Attendance, Timeline {
}
// which code gets called?
new TimeTravelingStudent().present();
¿Esto ya se ha definido como parte de JDK 8?
Encontré a los dioses de Java hablando de algo similar aquí http://cs.oswego.edu/pipermail/lambda-lib/2011-February/000068.html , pero es parte de una lista de correo privada y no puedo preguntarles directamente.
Consulte esto para obtener más detalles sobre cómo se utilizarán los valores predeterminados en JDK 8 y extender la interfaz de la colección para admitir lambdas: https://oracleus.wingateweb.com/published/oracleus2011/sessions/25066/25066_Cho223662.pdf
Respuestas:
La respuesta a la operación duplicada es:
Mi respuesta a su pregunta es: Sí, es una forma de herencia múltiple, porque puede heredar el comportamiento de diferentes padres. Lo que falta es heredar estados, es decir, atributos.
fuente
Sé que esta es una publicación antigua, pero como estoy trabajando con estas cosas ...
Tendrá un error del compilador, indicándole que:
fuente
Hay dos escenarios:
1) Primero, eso se mencionó, donde no hay una interfaz más específica
public interface A { default void doStuff(){ /* implementation */ } } public interface B { default void doStuff() { /* implementation */ } } public class C implements A, B { // option 1: own implementation // OR // option 2: use new syntax to call specific interface or face compilation error void doStuff(){ B.super.doStuff(); } }
2) Segundo, cuando HAY una interfaz más específica:
public interface A { default void doStuff() { /* implementation */ } } public interface B extends A { default void doStuff() { /* implementation */ } } public class C implements A, B { // will use method from B, as it is "closer" to C }
fuente
Sí, pero puede agregar captadores y definidores a su interfaz que las clases de implementación deben implementar. Sin embargo, las clases de implementación no heredan atributos. Entonces, AFAICS, es más como una solución de estilo de rasgo que una solución de estilo de herencia múltiple.
fuente
En resumen: es un error de tiempo de compilación, debe anular el método manualmente en la implementación.
Propósito del método predeterminado
El propósito principal de introducir el método predeterminado en Java 8 es hacer que la interfaz sea extensible, sin romper las implementaciones existentes (hay tantas bibliotecas Java de terceros).
Y
multiple inheritance
como en C ++ en realidad se pretende evitar, ese definitivamente no es el propósito del método predeterminado en Java.Cómo anular
2 opciones:
super
formato:<interface_name>.super.<method_name>();
Consejos:
public
palabra clave cuando la anule.fuente
Si alguien todavía está buscando una respuesta, en caso de que una clase implemente dos interfaces con el mismo método predeterminado, entonces la clase necesita resolver la falta de ambigüedad proporcionando una implementación propia. Consulte este tutorial para obtener más detalles sobre cómo funciona la herencia en los métodos predeterminados.
fuente
"¿Cómo distinguiremos los métodos?" Fue una pregunta que se puso en Stackoverflow y se refirió a esta pregunta métodos concretos en interfaces Java1.8
El siguiente es un ejemplo que debería responder a esa pregunta:
interface A{ default public void m(){ System.out.println("Interface A: m()"); } } interface B{ default public void m(){ System.out.println("Interface B: m()"); } } class C implements A,B { public void m(){ System.out.println("Concrete C: m()"); } public static void main(String[] args) { C aC = new C(); aC.m(); new A(){}.m(); new B(){}.m(); } }
La clase C anterior debe implementar su propio método concreto de las interfaces A y B. A saber:
public void m(){ System.out.println("Interface C: m()"); }
Para llamar a una implementación concreta de un método desde una interfaz específica , puede crear una instancia de la interfaz y llamar explícitamente al método concreto de esa interfaz
Por ejemplo, el siguiente código llama a la implementación concreta del método m () desde la interfaz A :
new A(){}.m();
El resultado de lo anterior sería:
Interfaz A: m ()
fuente
Hasta donde yo lo veo, no es una herencia múltiple porque son apátridas. Por lo tanto, los métodos de extensión virtual no admiten la funcionalidad completa de objetos o clases.
fuente