Si un tipo implementa dos interfaces, y cada interface
una define un método que tiene una firma idéntica, entonces, en efecto, solo hay un método, y no son distinguibles. Si, por ejemplo, los dos métodos tienen tipos de retorno en conflicto, entonces será un error de compilación. Esta es la regla general de herencia, anulación de métodos, ocultación y declaraciones, y se aplica también a posibles conflictos no solo entre 2 interface
métodos heredados , sino también un interface
y un súper class
método, o incluso solo conflictos debido a la eliminación de tipos de genéricos.
Ejemplo de compatibilidad
Aquí hay un ejemplo en el que tiene un interface Gift
, que tiene un present()
método (como en, presentar regalos), y también un interface Guest
, que también tiene un present()
método (como en, el invitado está presente y no ausente).
Presentable johnny
es a la vez a Gift
y a Guest
.
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { void present(); }
interface Presentable extends Gift, Guest { }
public static void main(String[] args) {
Presentable johnny = new Presentable() {
@Override public void present() {
System.out.println("Heeeereee's Johnny!!!");
}
};
johnny.present(); // "Heeeereee's Johnny!!!"
((Gift) johnny).present(); // "Heeeereee's Johnny!!!"
((Guest) johnny).present(); // "Heeeereee's Johnny!!!"
Gift johnnyAsGift = (Gift) johnny;
johnnyAsGift.present(); // "Heeeereee's Johnny!!!"
Guest johnnyAsGuest = (Guest) johnny;
johnnyAsGuest.present(); // "Heeeereee's Johnny!!!"
}
}
El fragmento anterior se compila y se ejecuta.
Tenga en cuenta que solo @Override
hay uno necesario !!! . Esto es porque Gift.present()
y Guest.present()
son " @Override
equivalentes" ( JLS 8.4.2 ).
Por lo tanto, johnny
solo tiene una implementación de present()
, y no importa cómo se trate johnny
, ya sea como Gift
o como a Guest
, solo hay un método para invocar.
Ejemplo de incompatibilidad
Aquí hay un ejemplo donde los dos métodos heredados NO son @Override
equivalentes:
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { boolean present(); }
interface Presentable extends Gift, Guest { } // DOES NOT COMPILE!!!
// "types InterfaceTest.Guest and InterfaceTest.Gift are incompatible;
// both define present(), but with unrelated return types"
}
Esto reitera además que heredar miembros de un interface
debe obedecer la regla general de las declaraciones de miembros. Aquí tenemos Gift
y Guest
definimos present()
con tipos de retorno incompatibles: uno void
al otro boolean
. Por la misma razón por la que no puede un void present()
y un boolean present()
tipo, este ejemplo da como resultado un error de compilación.
Resumen
Puede heredar métodos que sean @Override
equivalentes, sujetos a los requisitos habituales de anulación y ocultación de métodos. Como SON @Override
equivalentes, efectivamente solo hay un método para implementar, y por lo tanto no hay nada para distinguir / seleccionar.
El compilador no tiene que identificar qué método es para qué interfaz, porque una vez que se determina que son @Override
equivalentes, son el mismo método.
Resolver incompatibilidades potenciales puede ser una tarea difícil, pero ese es otro problema por completo.
Referencias