Reputation: 18408
I have the following situation :
abstract class X { abstract X someMethod (...) {...} }.
Now I want to constrain any implementation of X to have its 'someMethod' method return that particular implementation type, not just X :
class X1 extends X { X1 someMethod (...) {...} }.
class X1 extends X { X someMethod (...) {...} }. //want this to be flagged as an error
class X2 extends X { X1 someMethod (...) {...} }. //want this to be flagged as an error too
Is it possible to achieve this using Java generics ?
EDIT
Okay. I only asked the yes/no question and got a "yes". My fault. What I was actually interested in is "how do I write the declarations".
Upvotes: 12
Views: 17364
Reputation: 489
Here's an approach that lets you return a parameter type for this
:
AbstractFoo<T extends AbstractFoo<T>> {
/** Subclasses must implement to return {@code this}. */
protected abstract T getThis();
/** Does something interesting and returns this Foo */
public T inheritedThing {
/* blah di blah */
return getThis();
}
}
Upvotes: 2
Reputation: 29381
This works as well;
abstract class X<T> {
public abstract T yourMethod();
}
class X1 extends X<X1> {
public X1 yourMethod() {
return this;
}
}
class X2 extends X<X2> {
public X2 yourMethod() {
return this;
}
}
Upvotes: 21
Reputation: 70564
abstract class X<I extends X<I>> {
protected X(Class<I> implClazz) {
if (!getClass().equals(implClazz)) {
throw new IllegalArgumentException();
}
}
abstract I someMethod();
}
Rationale: You can not refer to the dynamic type in type bounds, hence the indirect check in the constructor.
Upvotes: 5
Reputation: 10355
This should work just fine:
class X<T> {
abstract T someMethod(...);
}
class X1<T1> extends X
T1 someMethod(...) {
...
}
}
Upvotes: 0