实现和集合

时间:2011-08-17 19:35:19

标签: java generics collections interface

为什么这不起作用......

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 个答案:

答案 0 :(得分:7)

因为虽然EdgeAction的子类型,但ArrayList<Action>不是ArrayList<Edge>的子类型。

改为使用ArrayList<? extends Edge>

你可以看看this tutorial's 4. Wildcard section,虽然我建议你仔细阅读,因为它真的很有帮助。

答案 1 :(得分:2)

这是因为类型ArrayList<E>上的E不是 covariant 。也就是说,您ArrayList<Derived>的{​​{1}}实例只能因为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 has indicated,实现此目的的正确方法是使用? extends Edge语法。

答案 2 :(得分:2)

香蕉水果。香蕉列表不是水果列表。

另外,有人可以构建一个香蕉列表,通过引用一个水果列表,然后你(正确地)在其中插入一个苹果。香蕉名单的所有者会理所当然地感到惊讶。

答案 3 :(得分:0)

因为泛型类型必须始终是相同的,而不是从它扩展的东西,你可以像这样重写它才能工作:

public ArrayList<? extends Edge> getEdges() {

return A;

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

}