una sirve que poo para modificadores metodos metodo interfaces implementacion ejemplo clase acceso abstractos abstracto abstracta java interface multiple-inheritance composition

sirve - Java: colisión del nombre del método en la implementación de la interfaz



modificadores de acceso java (7)

Si tengo dos interfaces, ambas bastante diferentes en sus propósitos, pero con la misma firma de método, ¿cómo hago que una clase implemente ambas cosas sin forzarme a escribir un solo método que sirva tanto para las interfaces como para escribir una lógica intrincada en el método? implementación que verifica para qué tipo de objeto se está haciendo la llamada e invoca el código apropiado?

En C #, esto se supera mediante lo que se llama implementación explícita de interfaz. ¿Hay alguna forma equivalente en Java?


El problema "clásico" de Java también afecta mi desarrollo de Android ...
La razón parece ser simple:
Más marcos / bibliotecas que tienes que usar, más fácilmente las cosas pueden estar fuera de control ...

En mi caso, tengo una clase BootStrapperApp heredada de android.app.Application ,
mientras que la misma clase también debería implementar una interfaz de plataforma de un marco MVVM para integrarse.
La colisión del método se produjo en un método getString () , que anuncian ambas interfaces y debe tener una implementación differenet en diferentes contextos.
La solución alternativa (feo ... MIMO) es utilizar una clase interna para implementar todos los métodos de plataforma , solo por un conflicto de firma de método menor ... en algún caso, dicho método prestado ni siquiera se usa (pero afecta a la semántica de diseño principal) .
Tiendo a estar de acuerdo en que la indicación explícita del contexto / espacio de nombres al estilo C # es útil.


La única solución que me vino a la mente es usar objetos referecia para el que desea implementar múltiples interfaces.

ej .: suponiendo que tienes 2 interfaces para implementar

public interface Framework1Interface { void method(Object o); }

y

public interface Framework2Interface { void method(Object o); }

puedes encerrarlos en dos objetos Facador:

public class Facador1 implements Framework1Interface { private final ObjectToUse reference; public static Framework1Interface Create(ObjectToUse ref) { return new Facador1(ref); } private Facador1(ObjectToUse refObject) { this.reference = refObject; } @Override public boolean equals(Object obj) { if (obj instanceof Framework1Interface) { return this == obj; } else if (obj instanceof ObjectToUse) { return reference == obj; } return super.equals(obj); } @Override public void method(Object o) { reference.methodForFrameWork1(o); } }

y

public class Facador2 implements Framework2Interface { private final ObjectToUse reference; public static Framework2Interface Create(ObjectToUse ref) { return new Facador2(ref); } private Facador2(ObjectToUse refObject) { this.reference = refObject; } @Override public boolean equals(Object obj) { if (obj instanceof Framework2Interface) { return this == obj; } else if (obj instanceof ObjectToUse) { return reference == obj; } return super.equals(obj); } @Override public void method(Object o) { reference.methodForFrameWork2(o); } }

Al final, la clase que querías debería ser algo así como

public class ObjectToUse { private Framework1Interface facFramework1Interface; private Framework2Interface facFramework2Interface; public ObjectToUse() { } public Framework1Interface getAsFramework1Interface() { if (facFramework1Interface == null) { facFramework1Interface = Facador1.Create(this); } return facFramework1Interface; } public Framework2Interface getAsFramework2Interface() { if (facFramework2Interface == null) { facFramework2Interface = Facador2.Create(this); } return facFramework2Interface; } public void methodForFrameWork1(Object o) { } public void methodForFrameWork2(Object o) { } }

ahora puede usar los métodos getAs * para "exponer" su clase


No hay una manera real de resolver esto en Java. Podría usar clases internas como una solución alternativa:

interface Alfa { void m(); } interface Beta { void m(); } class AlfaBeta implements Alfa { private int value; public void m() { ++value; } // Alfa.m() public Beta asBeta() { return new Beta(){ public void m() { --value; } // Beta.m() }; } }

Aunque no permite AlfaBeta de AlfaBeta a Beta , los AlfaBeta son generalmente malvados, y si se puede esperar que una instancia de Alfa menudo también tenga un aspecto Beta , y por alguna razón (generalmente la optimización es la única razón válida), desea poder convertirlo a Beta , podría hacer una interfaz secundaria de Alfa con Beta asBeta() en ella.


No, no hay forma de implementar el mismo método de dos maneras diferentes en una clase en Java.

Eso puede conducir a muchas situaciones confusas, por lo que Java lo ha rechazado.

interface ISomething { void doSomething(); } interface ISomething2 { void doSomething(); } class Impl implements ISomething, ISomething2 { void doSomething() {} // There can only be one implementation of this method. }

Lo que puedes hacer es componer una clase de dos clases que cada una implemente una interfaz diferente. Entonces esa clase tendrá el comportamiento de ambas interfaces.

class CompositeClass { ISomething class1; ISomething2 class2; void doSomething1(){class1.doSomething();} void doSomething2(){class2.doSomething();} }


Puede usar un patrón de Adaptador para que funcionen. Cree dos adaptadores para cada interfaz y úselos. Debería resolver el problema.


Si se encuentra con este problema, es más probable porque está utilizando la herencia donde debería usar la delegación . Si necesita proporcionar dos interfaces diferentes, aunque similares, para el mismo modelo subyacente de datos, debe utilizar una vista para proporcionar acceso a los datos de manera económica mediante otra interfaz.

Para dar un ejemplo concreto para este último caso, supongamos que desea implementar Collection y MyCollection (que no hereda de Collection y tiene una interfaz incompatible). Puede proporcionar las Collection getCollectionView() y MyCollection getMyCollectionView() que proporcionan una implementación ligera de Collection y MyCollection , utilizando los mismos datos subyacentes.

Para el primer caso ... supongamos que realmente quieres una matriz de enteros y una serie de cadenas. En lugar de heredar de List<Integer> y List<String> , debe tener un miembro de tipo List<Integer> y otro miembro de tipo List<String> , y hacer referencia a esos miembros, en lugar de intentar heredar de ambos. Incluso si solo necesitaras una lista de enteros, es mejor utilizar la composición / delegación sobre la herencia en este caso.


Todo bien cuando tienes el control total sobre todo el código en cuestión y puedes implementarlo por adelantado. Ahora imagine que tiene una clase pública existente utilizada en muchos lugares con un método

public class MyClass{ private String name; MyClass(String name){ this.name = name; } public String getName(){ return name; } }

Ahora necesita pasarlo al WizzBangProcessor, que requiere clases para implementar WBPInterface ... que también tiene un método getName (), pero en lugar de su implementación concreta, esta interfaz espera que el método devuelva el nombre de un tipo de procesamiento de Wizz Bang.

En C # sería un trvial

public class MyClass : WBPInterface{ private String name; String WBPInterface.getName(){ return "MyWizzBangProcessor"; } MyClass(String name){ this.name = name; } public String getName(){ return name; } }

En Java Tough, tendrá que identificar cada punto de la base de códigos desplegados existente donde necesita convertir de una interfaz a la otra. Seguro que la compañía WizzBangProcessor debería haber usado getWizzBangProcessName (), pero también son desarrolladores. En su contexto getName estaba bien. En realidad, fuera de Java, la mayoría de los otros lenguajes basados ​​en OO lo admiten. Java es raro al forzar que todas las interfaces se implementen con el mismo método NAME.

La mayoría de los otros lenguajes tienen un compilador que está más que feliz de tomar una instrucción para decir "este método en esta clase que coincide con la firma de este método en esta interfaz implementada es su implementación". Después de todo, el objetivo de definir interfaces es permitir que la definición se abstraiga de la implementación. (Ni siquiera me permite comenzar a tener métodos predeterminados en Interfaces en Java, y mucho menos sobrescribirlos por defecto ... porque seguro, todos los componentes diseñados para un coche de carretera deberían poder chocar contra un auto volador y simplemente funcionar - oye ambos son autos ... Estoy seguro de que la funcionalidad predeterminada de decir que su navegación por satélite no se verá afectada con las entradas predeterminadas de cabeceo y balanceo, ¡ya que los autos solo se desvían!