membersound
membersound

Reputation: 86915

How to use generics with inheritance?

I wrote some generics with inheritance, but cannot get it to work typesafe. My goal is to provide a general BaseService on that I can exection the action(base) method, no matter if the base object is a Foo extends Base or Bar extends Base.

The following does not work, why?

class Base;
class Foo extends Base;

interface BaseService<T extends Base> {
    void action(T base);
}

class FooService implements BaseService<Foo> {
    void action(Foo foo) {
    }
}


//usage:
//complains that the method is not applicable for the argument,
//and that I should change action(T) to action(Base). Why?
Base base;
getService().action(base);


//just to demonstrate the problem
BaseService<? extends Base> getService() {
    return new FooService();
}

Upvotes: 2

Views: 108

Answers (1)

herman
herman

Reputation: 12305

Generics exist for the purpose of static type checking. As you write

My goal is to provide a general BaseService on that I can exection the action(base) method, no matter if the base object is a Foo extends Base or Bar extends Base.

you indicate that you don't want any static type checking. So to accomplish that, the argument type should be Base instead of T.

As the return type of getService() is BaseService<? extends Base>, the compiler can't even know what T is (other than that it's some unknown subtype of Base) so you can't call the action method at all. But even if the return type of getService() would be FooService, the argument type T would be Foo, so you could not call it with type Base.

You should probably think a bit more about what you actually want the compiler to check by the use of generics.

Upvotes: 1

Related Questions