Реализации и Коллекции - PullRequest
       46

Реализации и Коллекции

2 голосов
/ 17 августа 2011

Почему это не работает ...

public ArrayList<Edge> getEdges() {

return A;

//A is an Arraylist of type 'Action'. Action implements Edge.

}

интерфейс Edge включает в себя: public ArrayList getEdges ();

, хотя это работает.

public Edge getEdges() {

return B;

//B is an 'Action'. Action implements Edge.

}

интерфейс Edge включает в себя: public Edge getEdges ();

Спасибо, Чет

Ответы [ 4 ]

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

Поскольку Edge является подтипом Action, ArrayList<Action> не является подтипом ArrayList<Edge>.

Используйте ArrayList<? extends Edge> вместо.

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

2 голосов
/ 17 августа 2011

Банан - это фрукт.Список бананов не является списком фруктов.

В противном случае кто-то может составить список бананов, передать вам ссылку на список фруктов, и вы (правильно) вставите в него яблоко.Владелец списка бананов будет по праву удивлен.

2 голосов
/ 17 августа 2011

Это потому, что ArrayList<E> не является ковариантным для типа E. То есть вы не можете заменить экземпляр ArrayList<Derived> на ArrayList<Base> только потому, что Derived наследуется от Base.

Рассмотрим этот случай: String наследуется от Object; однако , если это означает, что вы можете использовать ArrayList<String> в качестве ArrayList<Object>, тогда будет возможен следующий код:

ArrayList<Object> list = new ArrayList<String>();
list.add(new Integer(5)); // Integer inherits from Object

Выше не может работать, потому что вы не можете добавить Integer к ArrayList<String>. Если бы вы могли, то это могло бы произойти:

ArrayList<String> stringList = (ArrayList<String>)list;
String string = stringList.get(0); // Not a string!

Как и Ziyao указал , правильный способ реализовать это - использовать синтаксис ? extends Edge.

0 голосов
/ 17 августа 2011

Поскольку универсальный тип всегда должен быть одним и тем же , а не то, что из него следует, вы можете переписать его так, чтобы он работал:

public ArrayList<? extends Edge> getEdges() {

return A;

//A is an Arraylist of type 'Action'. Action implements Edge.

}
...