Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java generics to enforce return type of abstract method

Tags:

java

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".

like image 849
Erwin Smout Avatar asked Oct 26 '09 22:10

Erwin Smout


2 Answers

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;
    }
}
like image 96
Björn Avatar answered Oct 04 '22 19:10

Björn


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.

like image 21
meriton Avatar answered Oct 04 '22 21:10

meriton