2013-04-01 4 views
2

Я написал несколько дженериков с наследованием, но не могу заставить его работать с типами. Моя цель состоит в том, чтобы предоставить общее число BaseService, что я могу вывести метод action(base), независимо от того, является ли объект baseFoo extends Base или Bar extends Base.Как использовать дженерики с наследованием?

Следующие не работают, почему?

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(); 
} 
+0

Возможный дубликат «[Is« Список »подкласс« Список »? Почему не генерируются генетические средства Java, неявно полиморфные?] (Http://stackoverflow.com/questions/2745265/is-listdog-a- подкласс-оф-listanimal-почему-ARENT-Javas-дженериков-неявные) «. – wchargin

+0

Если да, что я могу сделать, чтобы заставить мой пример работать? – membersound

+0

Это уже типичный. Слишком типично. Я не думаю, что для этого вам нужны Generics. – EJP

ответ

1

Дженерики существуют для целей проверки статического типа. Когда вы пишете

Моя цель состоит в том, чтобы предоставить общий базовый сервис, чтобы я мог выполнить метод действия (базы), независимо от того, является ли базовый объект Foo расширением Base или Bar extends Base.

Вы указываете, что вам не нужна статическая проверка типа. Для этого тип аргумента должен быть Base вместо T.

Как возвращаемый тип getService() является BaseService<? extends Base>, компилятор даже не может знать, что T есть (кроме того, что это какой-то неизвестный подтип Base), так что вы не можете вызвать метод action вообще. Но даже если возвращаемый тип getService() будет FooService, аргумент типа T будет Foo, поэтому вы не могли назвать его с типом Base.

Возможно, вам стоит подумать немного больше о том, что вы действительно хотите, чтобы компилятор проверял использование дженериков.

Смежные вопросы