今天科比正式退役,在未来的日子里,也许还会有像科比一样有天赋又努力的球员出现,但我们却不再有青春去追随了。
— 沃茨・其索特
1 什么是协变与逆变
刚开始看到协变 (Covariance) 和逆变 (Contravariance) 的时候,差点晕菜,反复查了一些资料,才稍有些自己的体会,难免有理解不对的地方,欢迎指出 :]
在计算机科学和类型的领域内来看,变化 (variance) 这个词指的是两个类型之间的关系是如何影响从它们衍生出的两种复杂类型之间的关系的。相对于原始类型,这两种复杂类型之间的关系只能是不变 (invariance),协变 (covariance) 和逆变 (contravariance) 之中的某一种。
这段比较拗口,我们一步一步拆解,既然上面提到了两个类型之间的关系,在主流的编程观念里,类型之间的关系中通常会包含子类型 (subtype) 和 父类型 (supertype)。
首先假设 Cat 是 Animal 的子类,就是说 Cat 是 Animal 的 subtype,可以看作上面的 “原始类型”,然后有两个衍生出来的 List<Cat>和 List<Animal>类型,就是从 Cat 和 Animal 衍生出来的两种复杂类型。
那么我们就可以这么来解释协变和逆变了:
- 协变: 如果说
List<Cat> 也是 List<Animal>的 subtype,也就是衍生类型的关系和原来类型( Cat 与 Animal)的关系是一致的,那我们就说 List 是和它的原来类型协变(共同变化)的。
- 逆变:如果说
List<Cat> 是 List<Animal>的supertype,也就是衍生类型的关系和原来类型( Cat 与 Animal)的关系是相反的,那我们就说 List 是和它的原来类型逆变(反变)的。
- 不变:如果说
List<Cat> 既不是 List<Animal>的 subtype,也不是 supertype,也就是说没有关系,则说是不变的。