Search code examples
javagenericsinheritanceinterfacegeneric-type-argument

Java Interface with generics shall accept subclass as typeargument


I have the following class hierarchy by now:

interface Interface<T> {
    boolean isGreaterThan(T other);
}
class Base implements Interface<Base> {
    public boolean isGreaterThan(Base other) {
        return true;
    }
}
class Subclass extends Base {
    ... //note that I dont need to implement or overwrite isGreaterThan() here
}
class Wrapper<E extends Interface<E>> {
    protected List<E> list;
    ...
}
class Test {
    public static void main(String[] args) {
        Wrapper<Subclass> = new Wrapper<Subclass>(); //This line produces the error
    }
}

I get the following error message:

Type parameter 'Subclass' is not within its bound; should implement 'Interface<Subclass>'

My Question is: How can I tell java, that the Interface should accept any element E which extends T? Or is the reason in Wrapper? I tried for the Wrapper:

class Wrapper<E extends Interface<? extends E>> {}

which rather produced errors in the body of wrapper, and did not change the original error.

Wrapper<Base> wrapper = new Wrapper<Base>();

works just fine... how can I make

Wrapper<Subclass> wrapper = new Wrapper<Subclass>();

work as well? Is there a clean way without any casts? (Wildcards allowed)

Thanks!


Solution

  • try

    class Wrapper<E extends Interface<? super E>>
    

    just like Comparable, it is intuitively a 'contra-variant' type, therefore in most cases it should be used with <? super>. For example Collections.sort