覆盖较低的有界参数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了覆盖较低的有界参数相关的知识,希望对你有一定的参考价值。

我想知道为什么java不允许覆盖较低的有界泛型参数。

public interface NumberConsumer {
    public void accept(Consumer<? super Number> consumer);
}

public interface IntegerConsumer extends NumberConsumer {
    @Override
    public void accept(Consumer<? super Integer> consumer);
}

在上面的例子中,覆盖方法接受是完全安全的,因为NumberConsumer可以使用Numbers of Numbers,Serializables和Objects,而IntegerConsumer也可以使用所有这些和整数。

这也是不允许的,尽管也非常安全。

public interface IntegerPrinter {
    public void print(List<? extends Integer> list);
}

public interface NumberPrinter extends IntegerPrinter {
    @Override
    public void print(List<? extends Number> list);
}

在这里,NumberPrinter可以毫无问题地使用List<? extends Integer>

最后,在返回时允许一些类似的情况(或相反)。

public interface NumberListProducer {
    java.util.List<? extends Number> next();
}

public interface IntegerListProducer extends NumberListProducer {
    @Override
    java.util.List<? extends Integer> next();
}
答案

这不是泛型问题,而是java如何处理其overriding功能。

覆盖方法具有相同的名称,参数的数量和类型,以及返回类型作为它覆盖的方法。重写方法还可以返回由重写方法返回的类型的子类型。此子类型称为协变返回类型。

因此,仅在返回类型中的覆盖方法中允许继承类型。类型的精确匹配应该在方法参数中发生。

例如,以下情况会引发错误。

  1. interface PaterntInterface { public void accept(Integer consumer); } interface ChildInterface extends NumberConsumer { @Override public void accept(Number consumer); }
  2. interface PaterntInterface { public void accept(Number consumer); } interface ChildInterface extends NumberConsumer { @Override public void accept(Integer consumer); } 以下情况正确编译。
  3. interface PaterntInterface { public void accept(Integer consumer); } interface ChildInterface extends NumberConsumer { @Override public void accept(Integer consumer); }
  4. interface PaterntInterface { public void accept(Number consumer); } interface ChildInterface extends NumberConsumer { @Override public void accept(Number consumer); }

你的论点是你的第一个案例,

public interface NumberConsumer {
    public void accept(Consumer<? super Number> consumer);
}

public interface IntegerConsumer extends NumberConsumer {
    @Override
    public void accept(Consumer<? super Integer> consumer);
}

应该没问题,因为Consumer<? super Integer>Consumer<? super Number>的超类是无效的,因为重写需要方法参数类型的精确匹配。你的第二种情况也一样。第三种情况编译因为java.util.List<? extends Integer>java.util.List<? extends Number>的子类型,并且在方法覆盖中允许返回类型的继承

以上是关于覆盖较低的有界参数的主要内容,如果未能解决你的问题,请参考以下文章

Java里线程安全的有界容器的实现

带细节的有界可拖动元素

记一下要学习的内容和一些资源

Python kivy 较低的小部件位置

Python kivy 较低的小部件位置

关闭堆栈中较低的 ViewController 的行为不符合预期