Наследование Java и Обобщения - PullRequest
3 голосов
/ 10 августа 2011

У меня есть несколько классов, которые выглядят так:

MODEL

public abstract class BaseEntity<O extends Object> { ... }

public class Person extends BaseEntity<Person> { ... }

COMMAND

public abstract class BaseCommand<BE extends BaseEntity<BE>> { ... }

public class PersonCommand extends BaseCommand<Person> { ... }

СЕРВИС

public interface BaseService<BE extends BaseEntity<BE>> {
    public BE create(BaseCommand<BE> command);
}

public interface PersonService extends BaseService<Person> { ... }

SERVICE IMPL

public abstract class BaseServiceImpl<BE extends BaseEntity<BE>> implements BaseService<BE> { }

public class PersonServiceImpl extends BaseServiceImpl<Person> implements PersonService {
    public Person create(PersonCommand personCommand) { ... }
}

Класс PersonServiceImpl не будет компилироваться. Не признается, что метод create() реализует метод create() из интерфейса BaseService. Кто-нибудь может сказать, почему PersonCommand не распознается как BaseCommand<BE> (в списке параметров)?

1 Ответ

7 голосов
/ 10 августа 2011

При переопределении параметры метода не являются ковариантными (то есть подклассы должны принимать тип, который также принимает суперкласс, а не что-то более узкое).

Это потому, что люди могут использовать ваш PersonServiceImpl черезPersonService интерфейс, который будет принимать аргумент типа BaseCommand<Person>, который необязательно является PersonCommand (представьте, если вы создали второй класс, который расширил BaseCommand<Person>).

Если вы заставите свой метод приниматьпараметр типа BaseCommand<Person>, ваш код должен правильно скомпилироваться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...