resueltos polimorfismo interfaz interfaces ejercicios ejemplos clases clase abstractas abstracta java interface override

polimorfismo - interfaces en java ejercicios resueltos



Implementando dos interfaces en una clase con el mismo método. ¿Qué método de interfaz se reemplaza? (7)

Dos interfaces con los mismos nombres de método y firmas. Pero implementado por una sola clase, ¿cómo el compilador identificará qué método es para qué interfaz?

Ex:

interface A{ int f(); } interface B{ int f(); } class Test implements A, B{ public static void main(String... args) throws Exception{ } @Override public int f() { // from which interface A or B return 0; } }


Al igual que en la interfaz, solo estamos declarando métodos, la clase concreta que implementa estas dos interfaces comprende que solo hay un método (como usted describió, ambos tienen el mismo nombre en el tipo de devolución). por lo tanto, no debería haber ningún problema. Podrá definir ese método en una clase concreta.

Pero cuando dos interfaces tienen un método con el mismo nombre pero diferente tipo de retorno e implementan dos métodos en una clase concreta:

Por favor mira el siguiente código:

public interface InterfaceA { public void print(); } public interface InterfaceB { public int print(); } public class ClassAB implements InterfaceA, InterfaceB { public void print() { System.out.println("Inside InterfaceA"); } public int print() { System.out.println("Inside InterfaceB"); return 5; } }

cuando el compilador obtiene el método "public void print ()", primero se ve en InterfaceA y lo obtiene. Pero todavía da el error de tiempo de compilación que el tipo de devolución no es compatible con el método de InterfaceB.

Así que se vuelve loco para el compilador.

De esta forma, no podrá implementar dos interfaces que tengan un método del mismo nombre pero diferente tipo de devolución.


Bueno, si ambos son lo mismo, no importa. Implementa ambos con un único método concreto por método de interfaz.


En lo que respecta al compilador, esos dos métodos son idénticos. Habrá una implementación de ambos.

Esto no es un problema si los dos métodos son efectivamente idénticos, en el sentido de que deberían tener la misma implementación. Si son contractualmente diferentes (según la documentación de cada interfaz), estarás en problemas.


Esto se marcó como un duplicado de esta pregunta https://.com/questions/24401064/understanding-and-solving-the-diamond-problems-in-java

Necesita Java 8 para obtener un problema de herencia múltiple, pero todavía no es un problema de diamon como tal.

interface A { default void hi() { System.out.println("A"); } } interface B { default void hi() { System.out.println("B"); } } class AB implements A, B { // won''t compile } new AB().hi(); // won''t compile.

Como JB Nizet comenta, puedes arreglar esto, mi anulación.

class AB implements A, B { public void hi() { A.super.hi(); } }

Sin embargo, no tienes un problema con

interface D extends A { } interface E extends A { } interface F extends A { default void hi() { System.out.println("F"); } } class DE implement D, E { } new DE().hi(); // prints A class DEF implement D, E, F { } new DEF().hi(); // prints F as it is closer in the heirarchy than A.


Intente implementar la interfaz como anónimo.

public class MyClass extends MySuperClass implements MyInterface{ MyInterface myInterface = new MyInterface(){ /* Overrided method from interface */ @override public void method1(){ } }; /* Overrided method from superclass*/ @override public void method1(){ } }


No hay nada que identificar Las interfaces solo proscriben el nombre y la firma de un método. Si ambas interfaces tienen un método exactamente del mismo nombre y firma, la clase implementadora puede implementar ambos métodos de interfaz con un único método concreto.

Sin embargo, si los contratos semánticos de los dos métodos de interfaz son contradictorios, prácticamente ha perdido; entonces no puedes implementar ambas interfaces en una sola clase.


Si un tipo implementa dos interfaces, y cada interface define un método que tiene una firma idéntica, entonces, en efecto, solo hay un método, y no se distinguen. Si, por ejemplo, los dos métodos tienen tipos de devolución en conflicto, entonces será un error de compilación. Esta es la regla general de herencia, anulación de método, ocultación y declaraciones, y también se aplica a posibles conflictos no solo entre 2 métodos de interface heredados, sino también una interface y un método de superclase, o incluso conflictos debidos a borrado de tipos de genéricos .

Ejemplo de compatibilidad

Aquí hay un ejemplo donde tienes una interface Gift , que tiene un método present() (como en, presentación de obsequios), y también una interface Guest , que también tiene un método present() (como en, el invitado está presente y no ausente) )

Presentable johnny es tanto un Gift como un 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 de arriba se compila y ejecuta.

Tenga en cuenta que solo es necesario un @Override !!! . Esto se debe a que Gift.present() y Guest.present() son " @Override -equivalente" ( JLS 8.4.2 ).

Por lo tanto, johnny solo tiene una implementación de present() , y no importa cómo trate a johnny , ya sea como Gift o como Guest , solo hay un método para invocar.

Ejemplo de incompatibilidad

Aquí hay un ejemplo donde los dos métodos heredados NO son @Override -equivalente:

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 además reitera que heredar miembros de una interface debe obedecer la regla general de las declaraciones de los miembros. Aquí tenemos Gift y Guest definen present() con tipos de devolución incompatibles: uno void el otro boolean . Por la misma razón que no puede void present() un void present() y un boolean present() en un tipo, este ejemplo da como resultado un error de compilación.

Resumen

Puede heredar métodos que son @Override -equivalente, sujeto a los requisitos habituales de anulación y ocultamiento de métodos. Dado que SON @Override -equivalente, 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 cada interfaz, ya que una vez que se determina que son equivalentes a @Override , son el mismo método.

La resolución de posibles incompatibilidades puede ser una tarea difícil, pero ese es otro problema.

Referencias