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的详细信息,请关注图灵教育的其他相关文章!