如何在java List中使用继承?

时间:2015-07-11 15:41:15

标签: java inheritance

我想继承一个包含节点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);
    }
}

由于

3 个答案:

答案 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继承的任何类型。