
Java 中协变和逆变的函数参数
在 Java 中,函数参数在协变和逆变方面表现出不同的行为。这会影响方法签名与继承关系的交互方式。
协变(covariant)
协变允许函数在派生类中以更具体的类型声明参数。这意味着基类可以接收派生类型的对象作为参数,但反之则不行。
立即学习“Java免费学习笔记(深入)”;
class Animal {
public void eat(Animal food) {}
}
class Dog extends Animal {
@Override
public void eat(Animal food) {} // 协变:派生类参数类型更具体
}在此示例中,Animal 类的 eat 方法声明了一个 Animal 类型的参数。派生的 Dog 类可以覆盖 eat 方法并声明一个更具体的 Dog 类型的参数。这允许 Dog 类的方法接收 Dog 的对象,而 Animal 方法不能接收 Dog 的对象。
逆变(contravariant)
逆变允许函数在派生类中以更一般的类型声明参数。这意味着派生类可以接收基类型的对象作为参数,但反之则不行。
Shell本身是一个用C语言编写的程序,它是用户使用Linux的桥梁。Shell既是一种命令语言,又是一种程序设计语言。作为命令语言,它交互式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。它虽然不是Linux系统核心的一部分,但它调用了系统核心的大部分功能来执行程序、建立文件并以并行的方式协调各个程序的运行。因此,对于用户来说,shell是最重要的实用程序,深入了解和熟练掌握shell的特性极其使用方法,是用好Linux系统
interface Consumer{ void consume(T value); } class Cat implements Consumer {} // 逆变:派生类参数类型更一般 class Animal implements Consumer { @Override public void consume(Animal value) {} }
在此示例中,Consumer 接口声明了一个泛型方法 consume,接受一个 T 类型对象。Cat 类实现了 Consumer 接口并声明了一个更一般的 Animal 类型的参数。这允许 Cat 类的方法接收 Animal 的对象,而 Animal 方法不能接收 Cat 的对象。
实战案例:Comparable 接口
Comparable 接口定义了一个 compareTo 方法,用于比较两个对象的顺序。该接口支持协变和逆变。
interface Comparable{ int compareTo(T other); // 协变:返回类型更具体 }
Comparable 接口声明了一个协变返回类型。派生类可以覆盖 compareTo 方法并返回一个更具体的类型。
class Dog implements Comparable{ @Override public int compareTo(Dog other) { // 协变:返回类型更具体 return 0; } }
此外,Comparable 接口还支持逆变参数。这意味着派生类可以将更具体的类型作为参数传递。
class Animal implements Comparable{ @Override public int compareTo(Animal other) { // 逆变:参数类型更一般 return 0; } public int compareTo(Dog other) { // 逆变:参数类型更一般 return 0; } }
通过协变和逆变的参数,Java 允许方法签名与继承关系灵活交互,以创建可扩展且类型安全的代码。









