【问题标题】:Java inheritance with parameterized Lists带有参数化列表的 Java 继承
【发布时间】:2011-04-10 13:50:12
【问题描述】:

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

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&lt;B&gt; to ArrayList&lt;A&gt; C.java /bla/src/de/plai/test line 8 Java Problem

【问题讨论】:

  • 你应该抓住这个Generics 教程。

标签: java inheritance parameterized


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:
    ArrayList<? extends A> foo = new ArrayList<B>();
    

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

    也就是说,如果可能的话,您可以在一个仅包含 B 元素的实例化列表中插入一个类型为 A 的项。

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

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

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

    【讨论】:

      【解决方案3】:

      只是在上面发布相同的内容:) 不过..答案是一样的,这应该适合你。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-08
        • 1970-01-01
        • 2012-11-17
        • 1970-01-01
        • 2011-09-12
        • 1970-01-01
        相关资源
        最近更新 更多