I'm sure this has been answered 100 times but I'm not sure what to search for. I want to create an interface with an abstract method that enforces a parameter of self-type of the class that implements it.
Whew, that's a mouthful.
For example, I have an interface called Collider, with a method called isColliding. I have a class called Player that implements Collider. In my use case, only objects of the same sub-type of Collider will need to check if they're colliding with each other. I want Player to implement the method isColliding, but I want the function prototype to be enforced as isColliding(Player p), as opposed to isColliding(Collider c)
I've managed to implement what I'd consider a work-around, by declaring Collider as
public interface Collider<T extends Collider<T>> {
public abstract boolean isColliding(T other);
}
But when I declare my class that implements collider, the class prototype looks like this
public class Player implements Collider<Player>
This seems ugly and not necessarily as type-safe as I'd like. It seems like there should be a way to make that <Player> implied. My goal is to have the child class's Overridden function prototype look like this
public boolean isColliding(Player other)
Thanks in advance!
edit:
To give some more background:
I have a singleton class called Collision, which registers my objects that may collide with each other. Inside Collision I have a Hashmap declared as
HashMap<Class, ArrayList<Collider>> colliders
This is my data structure for storing the objects that may collide with each other. They are mapped by class, because my design only requires each class to check if it is colliding with itself. Collision has its own isColliding function to be called from within my objects that implement Collider. It looks like this
public <T extends Collider> boolean isColliding(T c) throws ColliderNotPopulatedException {
ArrayList<T> cList = (ArrayList<T>)colliders.get(c.getClass());
if (cList == null) {
throw new ColliderNotPopulatedException();
}
for (T otherC : cList) {
if (c != otherC && c.isColliding(otherC)) {
return true;
}
}
return false;
}
I'm getting NoSuchMethod errors as I try to call isColliding in this method, and I suspect it's because the self-typeness isn't implemented. Should I re-think my design? Are there patterns that would make this cleaner?
edit 2:
I managed to get past the error my casting 'otherC' as type (T) in the call to isColliding. It seems that this implementation will work for me. Thanks everyone for your help!