1700447294
在编程语言的类型框架中,协变和逆变是指宽类型和窄类型在某种情况下(如参数、泛型、返回值)替换或交换的特性,简单地说,协变是用一个窄类型替换宽类型,而逆变则是用宽类型覆盖窄类型。其实,在Java中协变和逆变我们已经用了很久了,只是我们没发觉而已,看如下代码:
1700447295
1700447296
class Base{
1700447297
1700447298
public Number doStuff(){
1700447299
1700447300
return 0;
1700447301
1700447302
}
1700447303
1700447304
}
1700447305
1700447306
class Sub extends Base{
1700447307
1700447308
@Override
1700447309
1700447310
public Integer doStuff(){
1700447311
1700447312
return 0;
1700447313
1700447314
}
1700447315
1700447316
}
1700447317
1700447318
子类的doStuff方法返回值的类型比父类方法要窄,此时doStuff方法就是一个协变方法,同时根据Java的覆写定义来看,这又属于覆写。那逆变是怎么回事呢?代码如下:
1700447319
1700447320
class Base{
1700447321
1700447322
public void doStuff(Integer i){
1700447323
1700447324
}
1700447325
1700447326
}
1700447327
1700447328
class Sub extends Base{
1700447329
1700447330
public void doStuff(Number n){
1700447331
1700447332
}
1700447333
1700447334
}
1700447335
1700447336
子类的doStuff方法的参数类型比父类要宽,此时就是一个逆变方法,子类扩大了父类方法的输入参数,但根据覆写定义来看,doStuff不属于覆写,只是重载而已。由于此时的doStuff方法已经与父类没有任何关系了,只是子类独立扩展出的一个行为,所以是否声明为doStuff方法名意义不大,逆变已经不具有特别的意义了,我们来重点关注一下协变,先看如下代码是否是协变:
1700447337
1700447338
public static void main(String[]args){
1700447339
1700447340
Base base=new Sub();
1700447341
1700447342
}
1700447343
[
上一页 ]
[ :1.700447294e+09 ]
[
下一页 ]