java - 给出在 Java 中重载和覆盖的情况下演示协变和逆变的函数示例?

标签 java covariance contravariance

请举一个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 class)的参数(但同样,完全履行 Super#doSomething 的契约)

注意:此示例不适用于 Java。 Java 编译器会重载并且不会覆盖 doSomething() 方法。其他语言确实支持这种逆变方式。

泛型

这也适用于泛型:

List<String> aList...
List<? extends Object> covariantList = aList;
List<? super String> contravariantList = aList;

您现在可以访问 covariantList 的所有不带泛型参数的方法(因为它必须是“扩展对象”的东西),但 getter 可以正常工作(因为返回的对象将始终是“对象”类型)

contravariantList 则相反:您可以使用泛型参数访问所有方法(您知道它必须是“String”的父类(super class),因此您始终可以传递一个),但没有 getter (返回的类型可以是 String 的任何其他父类(super class)型)

关于java - 给出在 Java 中重载和覆盖的情况下演示协变和逆变的函数示例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2501023/

相关文章:

java - 为 JLabel 中包含的超链接添加事件

java - SessionContext.getBusinessObject() 的返回值与 bean 中使用的 'this' 关键字有何不同?

java - Java中的协方差和重载

Scala 的位置方差

python - python 协议(protocol)中的泛型 - 协方差和逆变

ienumerable - 共/逆变? Tuple<string, IEnumerable<string>> 不满足 List<string>

C# : Is Variance (Covariance/Contravariance) another word for Polymorphism?

java - 具有两个以不同对象为父对象的构造函数的类

java - 如何使用抽象类的引用变量访问具体类的成员

scala - 为什么 Promise 不能是协变的