「协变java」洛伦兹协变

博主:adminadmin 2023-01-18 06:42:05 349

今天给各位分享协变java的知识,其中也会对洛伦兹协变进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

Java中什么是协变?怎样进行协变?

协变,就是父类和子类保持相同形式的变化,但是协变有时候倍支持,有时候不被支持

比如,在数组中,协变是支持的

比如

class Parent{}

class Child extends Parent{}

那么 Child[]可以赋值给 Parent[] ,这个就是协变

但是,在泛型中,协变就不可以

比如 虽然Child extends Parent

但是,假设有个 TestT,则 TestChild不可以赋值给TestParent,这2者毫无关系

在java中,什么是协变返回类型?

在Java1.4及以前,子类方法如果要覆盖超类的某个方法,必须具有完全相同的方法签名,包括返回值也必须完全一样。

Java5.0放宽了这一限制,只要子类方法与超类方法具有相同的方法签名,或者子类方法的返回值是超类方法的子类型,就可以覆盖。

注意:"协变返回(covariant return)",仅在subclass(子类)的返回类型是superclass(父类)返回类型的extension(继承)时才被容许。

什么是协变, 逆变?

java中协变跟逆变是对泛型类的继承关系的表述.

如:

ListNumber 和 ListInteger 之间是没有继承关系的.

但是直观上会觉得, Integer 是 Number 的子类, 所以 ListInteger 应是 ListNumber 的子类.

如果想要这种效果, 就要用协变.

List? extends Number 这样 ListInteger 就能成为List? extends Number 子类, 也就是可以赋值

这里如果你想要相反的效果, 则用逆变, List? super Number 这样继承关系就会相反.

那么什么时候用协变,逆变?

协变主要是用在函数的返回值上,逆变用在函数参数上,这样的规则也就能遵循 里氏替换原则 .

如 Function , 在这里 R 作为函数的返回值, 所以这个泛型要协变, 而 T 用在函数的参数上所以要用逆变

这里举个例子

假设有以下继承关系:

车 轿车 标准轿车 高级轿车

现在有一个人声称自己能修理所有的标准轿车, 所以发出了以下公告:

假设我现在有 List轿车 和 List高级轿车

那么这个人到底能修理哪个呢? 从上面的函数声明来看都不可以.

再来看看这个人的声明

他说能够修理所有 标准轿车

那么因为标准轿车扩展了轿车, 所以如果能够修理标准轿车, 那么应当可以修理轿车

所以这个函数应当可以接受所有 标准轿车 的父类

也就是说 List轿车 能够传入 以 List标准轿车 为参数的函数

换句话说 List轿车 是 List标准轿车 的子类, 这样才能传入参数

所以上面的公告要用逆变, 改成如下:

也许也不会有人想把自己的高级轿车交给这家伙.

以此类推, 函数的返回值应当用协变, 这样既能满足 里氏替换原则 了

协变java的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于洛伦兹协变、协变java的信息别忘了在本站进行查找喔。