Reputation: 555
How can i make an interface in java with a function that accepts a parameter of the type that extends the interface?
For example take the interface ISelfComparable
if class A extends it then i would expect it to implement
bool compareTo(A other)
but if class B extends it then i would expect it to implement
bool compareTo(B other)
I know i can use a generic interface but it seems incorrect because it doesn't make any sense for A to extend ISelfComparable<B>
If this is impossible, what is the best practice in this kind of situation?
Upvotes: 1
Views: 76
Reputation: 49794
The usual solution is self-bounded generics, as seen in the Enum
class.
interface Example<T extends Example<T>> {
void foo(T t);
}
public class ExampleImpl implements Example<ExampleImpl> {
@Override
public void foo(ExampleImpl example) {
}
}
How it works is a bit dizzying, but is explained very well here for example. There is also a very good answer on the subject here.
Note that it isn't foolproof, as it allows this:
public class ExampleImpl2 extends Example<ExampleImpl {
@Override
public void foo(ExampleImpl example) {
}
}
But in practice the self-bounded idiom is used to express exactly the sort of thing you're after.
If you really, really, really need the parameter object to always be the exact same class as this
, you have to do a runtime check. (It also raises the question of why you need this, but that would take us way off topic.)
Upvotes: 2
Reputation: 6300
There is a way to check the type of parameter but only in runtime. For example you can implement type checking in default method:
interface ISelfComparable {
default boolean compareTo(ISelfComparable param) {
if (this.getClass() != param.getClass()) {
throw new IllegalArgumentException();
}
...
}
}
Then each implementation of this interface should look like this:
class A implements ISelfComparable {
@Override
public boolean compareTo(ISelfComparable param) {
ISelfComparable.super.compareTo(param);
...
}
}
In this case if you call new A().compareTo(new B());
then java.lang.IllegalArgumentException
will be thrown
Upvotes: 0
Reputation: 9648
Have a look at the class java.lang.Comparable
: it has an argument with the type of the objects that can be used int compareTo
.
By analogy:
public interface ISelfComparable<T extends ISelfComparable<T>> {
boolean compareTo(T other);
}
Upvotes: 0