举例说明在Java中重载和重写的情况下证明协方差和逆变的函数?[已关闭]
请展示 Java 中协方差和逆变的一个很好的例子。
请展示 Java 中协方差和逆变的一个很好的例子。
协方差:
class Super {
Object getSomething(){}
}
class Sub extends Super {
String getSomething() {}
}
Sub#getSomething 是协变的,因为它返回返回类型的 Super#getSomething 的子类(但填充了 Super.getSomething()的合约)
逆方差
class Super{
void doSomething(String parameter)
}
class Sub extends Super{
void doSomething(Object parameter)
}
Sub#doSomething是逆变的,因为它需要Super#doSomething参数的超类的参数(但是,再次,填充了Super#doSomething的合约)
注意:此示例在 Java 中不起作用。Java 编译器将重载并且不会重写 doSomething()-方法。其他语言确实支持这种反方差样式。
泛 型
这对于泛型也是可能的:
List<String> aList...
List<? extends Object> covariantList = aList;
List<? super String> contravariantList = aList;
您现在可以访问所有不采用泛型参数的方法(因为它必须是“扩展对象”的东西),但是getters将正常工作(因为返回的对象将始终是“Object”类型)covariantList
反之亦然:您可以使用泛型参数访问所有方法(您知道它必须是“String”的超类,因此您始终可以传递一个),但没有 getter(返回的类型可以是 String 的任何其他超类型)contravariantList
协方差:可迭代和迭代器。定义共变体或 几乎总是有意义的。 可以像 - 类型参数出现的唯一位置是方法的返回类型,因此可以安全地将其上放到 。但是如果你有扩展,你也可以分配给一个类型的变量。例如,如果要定义查找方法:Iterable
Iterator
Iterator<? extends T>
Iterator<T>
next
T
S
T
Iterator<S>
Iterator<? extends T>
boolean find(Iterable<Object> where, Object what)
您将无法将其与 和 一起调用,因此最好将其定义为List<Integer>
5
boolean find(Iterable<?> where, Object what)
逆方差:比较器。它几乎总是有意义使用,因为它可以像 一样使用。type 参数仅显示为方法参数类型,因此可以安全地传递给它。例如,如果你有一个,并且你想用那个比较器(是 的子类)对一个进行排序,你可以用:Comparator<? super T>
Comparator<T>
compare
T
DateComparator implements Comparator<java.util.Date> { ... }
List<java.sql.Date>
java.sql.Date
java.util.Date
<T> void sort(List<T> what, Comparator<? super T> how)
但不是与
<T> void sort(List<T> what, Comparator<T> how)