举例说明在 Java 中重载和覆盖的情况下协变和逆变的函数? [英] Give examples of functions which demonstrate covariance and contravariance in the cases of both overloading and overriding in 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())
逆变
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() 方法.其他语言确实支持这种逆变风格.
泛型
这也适用于泛型:
List<String> aList...
List<? extends Object> covariantList = aList;
List<? super String> contravariantList = aList;
您现在可以访问 covariantList
的所有不带泛型参数的方法(因为它必须是扩展对象"),但是 getter 可以正常工作(因为返回的对象将始终是对象"类型)
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 (返回的类型可能是 String 的任何其他超类型)
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)
这篇关于举例说明在 Java 中重载和覆盖的情况下协变和逆变的函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!