Erwin Smout
Erwin Smout

Reputation: 18408

Java generics to enforce return type of abstract method

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

Answers (5)

rjrjr
rjrjr

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

Bj&#246;rn
Bj&#246;rn

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

meriton
meriton

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

Robert J. Walker
Robert J. Walker

Reputation: 10355

This should work just fine:

class X<T> {
  abstract T someMethod(...);
}

class X1<T1> extends X
  T1 someMethod(...) {
    ...
  }
}

Upvotes: 0

uckelman
uckelman

Reputation: 26224

Yes. This is return type covariance.

Upvotes: 0

Related Questions