【问题标题】:Interface Evolution - Inherited return type接口演变 - 继承的返回类型
【发布时间】:2016-01-14 08:15:50
【问题描述】:

我有一个正在开发数据模型的应用程序(该应用程序处理新旧数据)。 现在我想用原始返回类型的演变来覆盖方法的返回类型:

public interface Section {

List<Item> getItems();
}

public interface Item {
    String getName();
}

public interface ItemEvolution extends Item {
      String getEvolution();
}
public interface SectionEvolution extends Section {
      List<ItemEvolution> getItems();
}

在这个星座中,我在 getItems() 处得到一个不兼容的返回类型,但我没有破坏父接口,因为 ItemEvolution 扩展了 Item。

我该如何处理?

我正在使用 Java 8

【问题讨论】:

标签: java inheritance


【解决方案1】:

List&lt;ItemEvolution&gt;List&lt;Item&gt; 不兼容(因为您可以将Item 添加到后者而不是前者)。这是泛型的常见缺陷。

一种解决方案是在Section 中使用List&lt;? extends Item&gt; 作为超类的返回类型:

public interface Section {
    List<? extends Item> getItems();
}

public interface SectionEvolution extends Section {
    // Or List<? extends ItemEvolution> if you might want to override this again.
    List<ItemEvolution> getItems();
}

【讨论】:

    【解决方案2】:

    在这种情况下,您应该使用泛型。

    public interface Section<E extends Item> {
    
        List<E> getItems();
    }
    
    public interface Item {
        String getName();
    }
    
    public interface ItemEvolution extends Item {
        String getEvolution();
    }
    
    public interface SectionEvolution extends Section<ItemEvolution> {
    }
    

    【讨论】:

    • 谢谢你——我想,我之前检查过——我快疯了。
    【解决方案3】:

    这个很好地解释了为什么您的案例不起作用:

    http://docs.oracle.com/javase/tutorial/java/generics/inheritance.html

    所以List&lt;ItemEvolution&gt; 不是List&lt;Item&gt; 的子类 - 所以您需要使用带有通配符的泛型,如此处所述 - 实际上这篇文章准确地解释了您的情况。

    http://docs.oracle.com/javase/tutorial/java/generics/subtyping.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-11
      • 2014-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-19
      • 1970-01-01
      相关资源
      最近更新 更多