【问题标题】:Java Interface with generics shall accept subclass as typeargument具有泛型的 Java 接口应接受子类作为类型参数
【发布时间】:2016-11-28 15:35:12
【问题描述】:

我现在有以下类层次结构:

interface Interface<T> {
    boolean isGreaterThan(T other);
}
class Base implements Interface<Base> {
    public boolean isGreaterThan(Base other) {
        return true;
    }
}
class Subclass extends Base {
    ... //note that I dont need to implement or overwrite isGreaterThan() here
}
class Wrapper<E extends Interface<E>> {
    protected List<E> list;
    ...
}
class Test {
    public static void main(String[] args) {
        Wrapper<Subclass> = new Wrapper<Subclass>(); //This line produces the error
    }
}

我收到以下错误消息:

Type parameter 'Subclass' is not within its bound; should implement 'Interface<Subclass>'

我的问题是:我如何告诉 java,接口应该接受任何扩展 T 的元素 E?还是 Wrapper 中的原因?我尝试了 Wrapper:

class Wrapper<E extends Interface<? extends E>> {}

它在包装器的主体中产生了错误,并且没有改变原始错误。

Wrapper<Base> wrapper = new Wrapper<Base>();

工作得很好... 我该怎么做

Wrapper<Subclass> wrapper = new Wrapper<Subclass>();

也可以吗? 有没有没有任何演员的干净方式? (允许使用通配符)

谢谢!

【问题讨论】:

  • class Wrapper&lt;E extends Interface&lt;? super E&gt;&gt;
  • 这并没有改变任何东西,谢谢你的帮助!
  • &lt;? super E&gt; :) 另见示例docs.oracle.com/javase/7/docs/api/java/util/…
  • 我试过了,但错误仍然存​​在;-)
  • 哦,我还有其他错误使您的建议复杂化,但我可以弄清楚,这是因为内部类泛型,我只需要输入您的 '?那里也扩展了'解决方案......现在整个事情都有效了!非常感谢!您想将此作为答案发布,以便我将其标记为答案吗?

标签: java generics inheritance interface generic-type-argument


【解决方案1】:

试试

class Wrapper<E extends Interface<? super E>>

就像Comparable一样,直观上它是'contra-variant'类型,因此在大多数情况下它应该与&lt;? super&gt;一起使用。例如Collections.sort

【讨论】:

  • 顺便说一句:我有一个内部类,它使用相同的接口,因此我必须添加 super E> 到内部类定义也是如此!
【解决方案2】:

做这样的事情:

class Base<T extends Base<T>> implements Interface<T> {
    public boolean isGreaterThan(T other) {
        return true;
    }
}

还有:

class Subclass extends Base<Subclass> {
    ... //note that I dont need to implement or overwrite isGreaterThan() here
}

【讨论】:

  • 非常感谢第一种方法!它现在适用于每个子类,但不再适用于基类本身?我的意思是: Wrapper wrapper = new Wrapper() 现在会产生错误,而 Wrapper 会起作用:/ 谢谢你的帮助!
  • 因为Base 现在是一个泛型类,所以在Wrapper&lt;Base&gt; 中使用的不带类型参数的Baseraw type
  • 我试图找出解决方法,但失败了。你能给我另一个提示吗?我将不胜感激!
  • 钟宇的答案适用于每个案例!不过还是谢谢!
猜你喜欢
  • 2017-11-08
  • 1970-01-01
  • 1970-01-01
  • 2021-01-25
  • 1970-01-01
  • 2016-05-18
  • 1970-01-01
  • 2022-06-11
  • 1970-01-01
相关资源
最近更新 更多