ts 协变和逆变 一个不怎么有趣的问题

原创
08/30 16:44
阅读数 119

https://jkchao.github.io/typescript-book-chinese/tips/covarianceAndContravariance.html#%E5%8D%8F%E5%8F%98%E4%B8%8E%E9%80%86%E5%8F%98

 

函数类型的父子关系中, 参数类型是逆变的, 返回值类型是协变的

对于函数接口f:  Dog->Dog来说

在使用的过程我, 我们只会将Dog类型传入

 

1,g: D1->D1

D1是Dog的子类, 会有自己的方法, 我们用f接口去接受g的实例时, 传入的是Dog, 但是g中可能会用到D1的方法, 造成错误

2,g: D1->Animal

和1一样, 参数我们只会传入Dog

3,g: Animal->Animal

由于Dog是Animal的子类, 传入的Dog一定拥有Animal的方法, 所以参数是ok的, 但是返回值是有问题的, Animal类型不具有Dog的方法, 要是我们需要调用返回值Dog的方法, 就会出错

4,g: Animal -> D1

这个函数实例是可以的, 参数中Animal类型兼容Dog, 在g中使用完全没有问题, 返回值是D1也就是Dog的子类, 也可以作为Dog使用

即 (Animal->D1) 是 (Dog -> Dog) 的子类型

其中返回值 D1是Dog的子类型, 但是参数Animal和Dog的父子类型倒置了

 

ts中参数类型是双向协变的, 使用 --strictFunctionTypes  --strict 强制修复

 

 

对于数组

List<Dog> 是不是 List<Animal> 的子类

如果列表不可变, 那么是子类, 并且是类型安全的, 其不变列表的参数类型是协变的

如果列表可变, 那么可能会在List<Animal>中添加一个cat, 造成一堆狗里面有一只猫的情况, 所以可变列表的参数类型必须是不变的, 既不能协变也不能逆变

java里面数组是可变的 也是协变的, 并不安全, 这也是java的泛型并不是安全的

 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部