我想继承一个包含节点ArrayList的DAG类。要继承ArrayList,我使用了ArrayList<? extends Node>
但仍然无法编译我的代码。这是代码:
public class DAG {
ArrayList<? extends Node> nodes;
Node root;
public DAG(Node root) {
nodes = new ArrayList<>();
this.root = root;
nodes.add(root);
}
}
由于
答案 0 :(得分:1)
您的ArrayList
属于通用类型,继承自Node
,而不是Node
,但您向其添加了Node
,这可能是错误的类型 - 导致编译错误,因为此操作可能不安全。 (见答案末尾的解释)
处理它的一种方法是将ArrayList
声明为ArrayList<Node>
,而不是ArrayList<? extends Node>
。
另一个选择是将DAG
类声明为泛型类:
public class DAG <T extends Node> {
ArrayList<T> nodes;
T root;
public DAG(T root) {
/...
}
}
为什么不安全?
请查看以下代码:
public static class A {
}
public static class B extends A {
}
public static class C extends A {
}
public static <T extends A> void foo(ArrayList<T> arr, A a) {
arr.add(a); //this fails at compilation
}
public static void main(String[] args) throws Exception {
ArrayList<B> arr = new ArrayList<>();
foo(arr, new C());
B b = arr.get(0);
}
如果添加成功 - 您将收到运行时错误!
答案 1 :(得分:0)
您需要了解ArrayList<? extends Node>
的含义。它基本上是一个ArrayList,其元素类型扩展为Node
。该元素可以是Node
或其他继承Node
的类型。
也许这就是你需要的:
class A {
}
class B extends A {
}
class C extends A {
}
List<T extends A> nodes = new ArrayList<>();
B b = new B();
C c = new C();
nodes.add(b);
nodes.add(c);
答案 2 :(得分:0)
在你的例子中我会做到:
public class DAG {
ArrayList<Node> nodes;
Node root;
public DAG(Node root) {
// ..
}
}
这样nodes
可以包含Node
类型的对象以及从Node
继承的任何类型。