带参数化列表的Java继承

时间:2011-04-10 13:50:13

标签: java inheritance parameterized

我有一个奇怪的继承问题,我不明白为什么它不起作用:

public interface A {  }

public interface B extends A {}


public class C {
void test() {
    ArrayList<A> foo = new ArrayList<B>();
    }
}

但是编译会给我以下错误

Type mismatch: cannot convert from ArrayList<B> to ArrayList<A> C.java /bla/src/de/plai/test line 8 Java Problem

3 个答案:

答案 0 :(得分:7)

一开始看似违反直觉,但即使班级BA的子类,List<B>也不是List<A>的子类。我在this earlier answer中给出了类似帖子中更详细的解释和示例。另请参阅this other answer以获取 Effective Java 2nd Edition 中相应项目的链接。

此问题的解决方案是使用通配符。因此,您应该将列表声明为

List<? extends A> foo = new ArrayList<B>();

答案 1 :(得分:4)

ArrayList<? extends A> foo = new ArrayList<B>();

A列表与B列表不同,因为您无法保证列表中内容的一致性。

即,如果可能,您可以在实例化的列表中插入类型A的项目,仅包含B元素。

当然,上述声明将阻止您将任何元素写入列表。这是一个只读声明。

将变量声明为接口而不是实现是一个很好的OOP原则:

List<? extends A> foo = new ArrayList<B>();

答案 2 :(得分:1)

就在上面发布相同:)尽管如此......答案是相同的,这应该适合你。

ArrayList<? extends A> foo = new ArrayList<B>();