【问题标题】:Inheritance Generics继承泛型
【发布时间】:2013-03-19 07:41:23
【问题描述】:

假设我有一个这样定义的抽象类:

public class Response<T> {
    private List<Response<T>> subResponses;
}

还有两个这样定义的子类:

public class SectionResponse extends Response<SectionResponse> {
}

public class FormResponse extends Response<FormResponse> {
}

基本上所有 Response 的子类都需要有一个相同类的列表。现在在代码的其他地方我想要一个可以包含任一子类的 Response 对象列表。

在不使用原始类型的情况下定义此列表的最佳方法是什么?我已经尝试过List&lt;? extends Response&lt;?&gt;&gt;,但我无法在这样定义的 List 上调用 add 方法,因为参数是参数化类型。

【问题讨论】:

  • List&lt;T extends Response&lt;T&gt;&gt;?只是大声思考。
  • @JanDvorak:这不是有效的 Java 语法

标签: java generics inheritance


【解决方案1】:

使用Put-Get-Rule。即,返回List&lt;? extends Response&lt;?&gt;&gt;,但接受List&lt;? super Response&lt;?&gt;&gt; 作为参数。在内部,您会将列表存储为 List&lt;Response&gt;

作为说明,我会警惕在界面上返回List&lt;? extends Response&lt;?&gt;&gt;,因为它可能会侵入消费者。在大多数情况下,最好让接口确定泛型类型,以便尽可能返回 List&lt;Response&lt;MyType&gt;&gt; 之类的内容。

【讨论】:

    【解决方案2】:

    你的Response 类应该这样定义:

    public class Response<T> {
        private List<T> subResponses;
    }
    

    这样SectionResponseFormResponse,正如声明的那样,将拥有自己的列表。

    现在,从字面上回答您的问题,对于可以包含其中任何一个的列表,您只需一个 List&lt;Response&lt;?&gt;&gt;

    但是,您可能想要的不止这些——您可能想要从列表中取出元素并对它们做点什么。如果您可以更具体地说明您需要做什么,我们可以为您提供进一步的帮助。

    【讨论】:

      【解决方案3】:

      我承认我不确定你到底想做什么,但这很有效,至少涉及到你描述的问题:

      public class Response<T extends Response> {
          private List<T> sl = new LinkedList<T>();
      
          protected void add(T resp) {
              sl.add(this);
          }
      }
      
      public class FormResponse extends Response<FormResponse> {
          public FormResponse() {
              add(this);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2018-09-27
        • 2015-09-15
        • 2017-10-28
        • 2011-05-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多