In Java, is it possible to define an interface that has a method that receives an argument of the implementing class?
interface:
public interface MyInterface { public <T is/extends of the type of the implementing class> void method(T object); }
class:
public class A implements MyInterface { public void method(A object) { ... } }
What I want to avoid is that a class could implement MyInterface with another class like itself.
So this should not be allowed:
public class A implements MyInterface<B> { public void method(B object) { ... } }
Edit:
Ok I try to describe in another way what I want to achieve. I want to have several classes that have a method that accepts an arg of that type of class. So additionally to class A from above lets say theres another class B that looks like this:
public class B implements MyInterface { public void method(B object) { ... } }
what booth classes A and B have in common is a method called "method" that receives an arg of the type of the class itself.
In my project I want to achieve the following. Im writing a little game and want to implement some kind of collision detection. basically I want to do this by doing some "smart" polymorphistic calls.
I defined an interface ICollisionReceiver that looks like this:
public interface ICollisionReceiver<T extends IShape> extends IShape { public boolean collides(T t); }
and I defined another interface like this:
public interface ICollisionChecker<T extends ICollisionChecker<T>> extends IShape { public void addCollisionReceiver(ICollisionReceiver<T> receiver); public void removeCollisionReceiver(ICollisionReceiver<T> receiver); }
Now for instance my player implements the interface ICollisionReceiver as the player receives collisions and handles them. This should be done in a generic way, so for instance I have boxes and circle, now the Player implements ICollisionReceiver < Box > and ICollisionReceiver < Circle > so I have both methods
@Override public boolean collides(final Box b) { ... return false; }
and
@Override public boolean collides(final Circle c) { ... return false; }
In my box and circle class I can register ICollisionReceivers and then I do the following in the update method:
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; }
this basically checks if this box collides with a certain receiver and then calls the receivers collides() method.
Now the point is, I want to make sure that both classes box and circle implement the ICollisionChecker interface only with their own type.
I explicitly can do this by doing something like this
public class Bonus extends AnimatedSprite implements ICollisionChecker<Bonus>...
but this is not very satisfying for me...
Sorry for the long post, I hope this makes it clear.
Java Generic Classes and SubtypingWe can subtype a generic class or interface by extending or implementing it. The relationship between the type parameters of one class or interface and the type parameters of another are determined by the extends and implements clauses.
What you want is not possible in Java, and is not useful.
So this should not be allowed:
Why not? What purpose does that serve? Generics is not for you to make arbitrary restrictions. Generics is only useful for eliminating casts that you would otherwise need, because it can prove that the cast is always safe.
As long as public class A implements MyInterface<B>
is type-safe, there is no point in making an arbitrary restriction that prohibits it.
You should simply define your interface as
public interface MyInterface<T> { public void method(T object); }
and you can define your class
public class A implements MyInterface<A> { public void method(A object) { } }
and if somebody else defines a class
public class B implements MyInterface<A> { public void method(A object) { } }
then so be it. Why do you care? What problem does it cause?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With