Возвратите ошибку в реализации интерфейса, используя дженерики - PullRequest
1 голос
/ 22 ноября 2011

У меня есть интерфейс, определяющий метод, подобный этому:

public List<IA> myMethod();

с IA другим интерфейсом.

В моей реализации метода я объявляю:

public List<A> myMethod() { /* Do something */ }

с A классом, реализующим IA.

Однако Java (или eclipse) это не нравится и заставляет меня иметь List<IA> в моей реализации myMethod.Поскольку A реализует IA, я не понимаю, почему это приводит к ошибке.

Итак, вот вопросы:

  • Почему у меня есть эта ошибка?
  • Каков наилучший способ ее избежать (зная, что у меня нет большой свободыпо коду)?

Ответы [ 2 ]

5 голосов
/ 22 ноября 2011

У вас есть эта ошибка, потому что она небезопасна с точки зрения безопасности типов.Подумайте:

// Interface declaration
List<Fruit> myMethod();

// Implemented by...
public List<Banana> myMethod() {
    return new ArrayList<Banana>();
}

// Called as:
List<Fruit> fruit = foo.myMethod();
fruit.add(new Apple());

Вы действительно хотите иметь возможность добавить Apple к ArrayList<Banana>?

Это можно исправить, изменив объявление на

List<? extends IA> myMethod();

Это предотвратит добавление вызовов в список (или установку значений в нем).

Если вы не можете изменить интерфейс, у вас будет иметь для возврата List<IA> Боюсь, что по вашему методу.

См. FAQ по обобщенным Java * для более подробной информации.

0 голосов
/ 22 ноября 2011

Поскольку в контракте, определенном в interface, указано, что myMethod должен возвращать список типа IA.

Как правило большого пальца: Ссылка на базовый класс может использоваться где угодно, когда требуется объект производного класса. , но, наоборот, НЕ верен. и это ошибка.

Чтобы избежать этой ошибки: всегда следуйте интерфейсу (контракту) как есть.

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