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)
逆变允许函数在派生类中以更一般的类型声明参数。这意味着派生类可以接收基类型的对象作为参数,但反之则不行。
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 允许方法签名与继承关系灵活交互,以创建可扩展且类型安全的代码。
以上就是Java中函数参数的协变 contravariance的详细内容,更多请关注php中文网其它相关文章!