java - interfaz - Métodos predeterminados e interfaces extendiendo otras interfaces.
java swing tutorial pdf español (1)
Esto es exactamente abordado por el JLS en 15.12.3. "Paso 3 de tiempo de compilación: ¿Es apropiado el método elegido?" .
Si el formulario es TypeName. súper . [TypeArguments] Identificador , entonces:
- […]
- Si TypeName denota una interfaz, sea
T
la declaración de tipo que encierra inmediatamente la invocación del método. Se produce un error de tiempo de compilación si existe un método, distinto de la declaración de tiempo de compilación, que anula ( §9.4.1 ) la declaración de tiempo de compilación de una superclase directa o una superinterfaz directa deT
El JLS continúa explicando por qué la regla está en su lugar:
En el caso de que una superinterfaz anule un método declarado en una interfaz de abuelo, esta regla evita que la interfaz de niño "omita" la anulación simplemente agregando al abuelo a su lista de superinterfaces directas. La forma adecuada de acceder a la funcionalidad de un abuelo es a través de la superinterfaz directa, y solo si esa interfaz elige exponer el comportamiento deseado.
Así que existe más o menos específicamente para evitar que hagas lo que estás tratando de hacer.
Pero el JLS también parece reconocer su solución:
(Alternativamente, el desarrollador es libre de definir su propia superinterfaz adicional que expone el comportamiento deseado con una invocación de super método).
Supongamos que hay dos interfaces Interface1
e Interface2
donde Interface2
extiende Interface1
.
interface Interface1 {
default void method() {
System.out.println("1");
}
// Other methods
}
interface Interface2 extends Interface1 {
@Override
default void method() {
System.out.println("2");
}
// Other methods
}
Supongamos que quiero crear una clase que implemente Interface2
pero quiero que method()
sea la versión en Interface1
. Si escribo
class MyClass implements Interface1, Interface2 {
public void method() {
Interface1.super.method();
}
}
Me sale el error de compilación:
calificador de tipo incorrecto en súper llamada predeterminada: interfaz redundante Interfaz1 se extiende por Interfaz2
Es posible solucionar esto creando una tercera interfaz:
interface Interface3 extends Interface1 {
default void method() {
Interface1.super.method();
}
}
Entonces:
class MyClass implements Interface1, Interface2, Interface3 {
public void method() {
Interface3.super.method();
}
}
Esto compila bien, y si hago una instancia de un nuevo MyClass
e invoco method()
, la salida es 1
como se esperaba.
Entonces, mi pregunta es que, dado que es tan fácil sortear la restricción que solo puede escribir InterfaceName.super.method()
para la interfaz más específica de una cadena, ¿cuál es el motivo de la restricción? ¿Qué problemas se evitan al no permitirle escribir Interface1.super.method()
en primer lugar?