Java 协变性 逆变性

在面向对象的计算机程序语言中,经常涉及到类型之间的转换,例如从具体类小猫到动物之间的类型转换(上行转换),或者从形状向三角形之间的转换(下行转换)。
我们之前往往都比较关注类型本身,却常常忽略类型转换的性质。最近在拜读《thinking in java》看到一些关于类型转换性质的比较抽象理论的内容,仔细研究一下,分享给大家。
我们将围绕如下三个核心名词:协变性(covariance)、逆变性(contravariance)和无关性(invariant)。他们都是用来描述类型转换的性质的术语,形式化的描述如下:

如果A和B是类型,f表示类型转换,≤表示子类型关系,(例如A≤B,表示A是B的子类)那么:
如果A≤B 则f(A) ≤ f(B) 那么 f是协变的
如果A≤B 则f(B) ≤ f(A) 那么 f 是逆变的

如果上面两种都不成立,那么f是无关的

例如java中,f(A) = List ,这里List声明如下:
class List{…}
我们可以理解泛型类List输入一个类型参数T,然后将T转换成类型List,这个过程本身是一个类型转换f。
我们举例A = Object,B=String,经过类型变换f以后f(A)=List,f(B) = List。
String ≤ Object 但是 f(A) ≤ f(b)却不成立。
所以上面的类型转换是无关的。

在Java语言中,有一些语法可以用协变性和逆变性来理解。
数组
例如 A = String, B = Object 我们这里有A≤B
f(A) = String[], f(B) = Object[]. 因为Object[] objects = new String[n]. 所以我们可以认为数组具有协变性。

X = Y

你可能感兴趣的:(Java 协变性 逆变性)