Si un tipo implementa dos interfaces, y cada interfaceuna 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 interfacemétodos heredados , sino también un interfacey un súper classmé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 johnnyes a la vez a Gifty 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 " @Overrideequivalentes" ( 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 Gifto 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 @Overrideequivalentes:
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 interfacedebe obedecer la regla general de las declaraciones de miembros. Aquí tenemos Gifty Guestdefinimos present()con tipos de retorno incompatibles: uno voidal 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 @Overrideequivalentes, 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 @Overrideequivalentes, son el mismo método.
Resolver incompatibilidades potenciales puede ser una tarea difícil, pero ese es otro problema por completo.
Referencias