
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)
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
逆变允许函数在派生类中以更一般的类型声明参数。这意味着派生类可以接收基类型的对象作为参数,但反之则不行。
interface Consumer<T> {
void consume(T value);
}
class Cat implements Consumer<Cat> {} // 逆变:派生类参数类型更一般
class Animal implements Consumer<Animal> {
@Override
public void consume(Animal value) {}
}在此示例中,Consumer 接口声明了一个泛型方法 consume,接受一个 T 类型对象。Cat 类实现了 Consumer 接口并声明了一个更一般的 Animal 类型的参数。这允许 Cat 类的方法接收 Animal 的对象,而 Animal 方法不能接收 Cat 的对象。
实战案例:Comparable 接口
Comparable 接口定义了一个 compareTo 方法,用于比较两个对象的顺序。该接口支持协变和逆变。
interface Comparable<T> {
int compareTo(T other); // 协变:返回类型更具体
}Comparable 接口声明了一个协变返回类型。派生类可以覆盖 compareTo 方法并返回一个更具体的类型。
class Dog implements Comparable<Dog> {
@Override
public int compareTo(Dog other) { // 协变:返回类型更具体
return 0;
}
}此外,Comparable 接口还支持逆变参数。这意味着派生类可以将更具体的类型作为参数传递。
class Animal implements Comparable<Animal> {
@Override
public int compareTo(Animal other) { // 逆变:参数类型更一般
return 0;
}
public int compareTo(Dog other) { // 逆变:参数类型更一般
return 0;
}
}通过协变和逆变的参数,Java 允许方法签名与继承关系灵活交互,以创建可扩展且类型安全的代码。

















