rawtypes method generic example java generics types

method - Java Generics: método de interfaz que recibe el argumento de tipo de la clase de implementación



rawtypes (3)

En Java, ¿es posible definir una interfaz que tenga un método que reciba un argumento de la clase implementadora?

interfaz:

public interface MyInterface { public <T is/extends of the type of the implementing class> void method(T object); }

clase:

public class A implements MyInterface { public void method(A object) { ... } }

Lo que quiero evitar es que una clase pueda implementar MyInterface con otra clase como la misma.

Así que esto no debe ser permitido:

public class A implements MyInterface<B> { public void method(B object) { ... } }





Editar:

Ok trato de describir de otra manera lo que quiero lograr. Quiero tener varias clases que tengan un método que acepte un argumento de ese tipo de clase. Entonces, además, a la clase A de arriba, digamos que hay otra clase B que se ve así:

public class B implements MyInterface { public void method(B object) { ... } }

Lo que las clases de caseta A y B tienen en común es un método llamado "método" que recibe un argumento del tipo de la clase en sí.

En mi proyecto quiero lograr lo siguiente. Estoy escribiendo un pequeño juego y quiero implementar algún tipo de detección de colisiones. Básicamente quiero hacer esto haciendo algunas llamadas polimorfistas "inteligentes".

Definí una interfaz ICollisionReceiver que se parece a esto:

public interface ICollisionReceiver<T extends IShape> extends IShape { public boolean collides(T t); }

y definí otra interfaz como esta:

public interface ICollisionChecker<T extends ICollisionChecker<T>> extends IShape { public void addCollisionReceiver(ICollisionReceiver<T> receiver); public void removeCollisionReceiver(ICollisionReceiver<T> receiver); }

Ahora, por ejemplo, mi reproductor implementa la interfaz ICollisionReceiver cuando el jugador recibe colisiones y las maneja. Esto debe hacerse de forma genérica, por ejemplo, tengo casillas y círculos, ahora el Jugador implementa ICollisionReceiver <Box> e ICollisionReceiver <Circle>, así que tengo ambos métodos

@Override public boolean collides(final Box b) { ... return false; }

y

@Override public boolean collides(final Circle c) { ... return false; }

En mi clase de caja y círculo puedo registrar ICollisionReceivers y luego hago lo siguiente en el método de actualización:

boolean conti = true; int i=0; while(conti && i<collisionReceivers.size()) { final ICollisionReceiver<Bonus> rec = collisionReceivers.get(i); if(this.collidesWith(rec)) { conti = rec.collides(this); } ++i; }

esto básicamente verifica si esta casilla choca con un receptor determinado y luego llama al método collides () de los receptores.

Ahora el punto es, quiero asegurarme de que tanto el cuadro de las clases como el círculo implementen la interfaz ICollisionChecker solo con su propio tipo.

Yo explícitamente puedo hacer esto haciendo algo como esto

public class Bonus extends AnimatedSprite implements ICollisionChecker<Bonus>...

pero esto no es muy satisfactorio para mi ...

Perdón por el largo post, espero que esto quede claro.


Bueno, esto es al menos posible:

public interface SelfImplementer<T extends SelfImplementer<T>> { void method(T self); }

Como puede ver, la declaración genérica se parece un poco a una recursión infinita y estoy bastante seguro de que si Java no tuviera borrado de tipo, sería - afortunadamente (?) Todos los genéricos son en realidad Objects después de que el compilador los ha tratado, por lo que Puedes hacerlo

public class Impl implements SelfImplementer<Impl> { @Override public void method(Impl self) { System.out.println("Hello!"); } }

y como era de esperar, este

public static void main(String[] args) { Impl impl = new Impl(); impl.method(impl); }

imprime

Hello!


Lo que quieres hacer es probablemente algo como esto:

public interface MyInterface <T extends A> { public void method(T object) { ... } } public class A implements MyInterface<A_or_class_extending_A> { ... }

Espero que esto haya ayudado!


Lo que quieres no es posible en Java, y no es útil.

Así que esto no debe ser permitido:

Por qué no? ¿Para qué propósito sirve eso? Lo genérico no es para que hagas restricciones arbitrarias. Los genéricos solo son útiles para eliminar los moldes que de otro modo necesitarías, porque pueden probar que el elenco siempre es seguro.

Mientras public class A implements MyInterface<B> es de tipo seguro, no tiene sentido hacer una restricción arbitraria que lo prohíba.

Simplemente debe definir su interfaz como

public interface MyInterface<T> { public void method(T object); }

y puedes definir tu clase

public class A implements MyInterface<A> { public void method(A object) { } }

Y si alguien más define una clase.

public class B implements MyInterface<A> { public void method(A object) { } }

entonces que así sea. ¿Por qué te importa? ¿Qué problema causa?