展示Java中的协方差和逆变?
请在Java中显示协方差和逆变的一个很好的例子。
Please show a good example for covariance and contravariance in Java.
协方差:
class Super {
Object getSomething(){}
}
class Sub extends Super {
String getSomething() {}
}
Sub#getSomething是协变的,因为它返回返回类型为Super#getSomething的子类(但是满足Super.getSomething()的合约)
Sub#getSomething is covariant because it returns a subclass of the return type of Super#getSomething (but fullfills the contract of Super.getSomething())
Contravariance
class Super{
void doSomething(String parameter)
}
class Sub extends Super{
void doSomething(Object parameter)
}
Sub#doSomething是逆变的,因为它需要Super#doSomething参数的超类参数(但是,再次填写Super#doSomething的合约)
Sub#doSomething is contravariant because it takes a parameter of a superclass of the parameter of Super#doSomething (but, again, fullfills the contract of Super#doSomething)
注意:这个例子没有在Java工作。 Java编译器会重载并且不会覆盖doSomething() - Method。其他语言确实支持这种逆转方式。
泛型
这也适用于泛型:
List<String> aList...
List<? extends Object> covariantList = aList;
List<? super String> contravariantList = aList;
您现在可以访问 covariantList的所有方法
不带泛型参数(因为它必须是extends Object),但getter工作正常(因为返回的对象将始终是Object类型)
You can now access all methods of covariantList
that doesn't take a generic parameter (as it must be something "extends Object"), but getters will work fine (as the returned object will always be of type "Object")
对于 contravariantList
,情况正好相反:您可以使用泛型参数访问所有方法(您知道它必须是String的超类) ,所以你总是可以传递一个),但没有getter(返回的类型可能是任何其他字符串的超类型)
The opposite is true for contravariantList
: You can access all methods with generic parameters (you know it must be a superclass of "String", so you can always pass one), but no getters (The returned type may be of any other supertype of String)