Kotlin中泛型的协变

kotlin 复制代码
interface Shape

class Circle : Shape

fun main() {
    val shapes1: List<Shape> = listOf<Circle>()
    val shapes2: MutableList<Shape> = mutableListOf<Circle>()
}

如上代码,第一行赋值语句是OK的,第二行赋值语句在编辑器上直接就报错了。为什么会这样,这需要理解协变概念。

只读集合类型是协变的,相反,可变集合不是协变的。

协变不协变有什么用?

协变的话,父类型就可以接收子类型,比如:

kotlin 复制代码
val shapes1: List<Shape> = listOf<Circle>()

如上代码,List是一个协变类型,所以泛型Shape可以接收Circle,这是没问题的,因为List是只读的,那么List中的元素就只可能是Circle类型,不会发生改变。

而非协变的话父类型就不能接收子类型,如下:

kotlin 复制代码
val shapes2: MutableList<Shape> = mutableListOf<Circle>()

如上代码,在编辑器中是直接报错的,因为MutableList不是只读的,它可以增、删除 、改,比如shapes2.add(Retangel()),但我们的集合实际是想只保存Circle的,它会导致异常,示例如下:

kotlin 复制代码
interface Shape

class Circle : Shape
class Rectangle: Shape

fun main() {
    val circles: MutableList<Circle> = mutableListOf()
    val shapes: MutableList<Shape> = circles
    shapes.add(Rectangle())
    val circle: Circle = circles[0] // 其实它是一个Rectangle
}

如上代码,如果非协变类型可以子类给父类,这将导致异常,所以在编辑器中这种赋值时会直接报错。

另外,协变和非协变,是看左边的类型,如下代码:

kotlin 复制代码
val shapes1: List<Shape> = listOf<Circle>()
val shapes2: List<Shape> = mutableListOf<Circle>()

如上代码,左边的类型是List,这是只读类型,所以它是协变的,那么它就能接收子类型的集合,不管这个子类型是List还是MutableList都可以。

如果不是协议的,则不能接收子类型,不管子类型是List还是MutableList都不可以。示例如下:

kotlin 复制代码
val shapes1: MutableList<Shape> = listOf<Circle>()
val shapes2: MutableList<Shape> = mutableListOf<Circle>()

如上代码,左边的类型是MutableList,不是只读的,所以它不是协变的,所以不能接收子类型,不管子类型是List还是MutableList都不可以。

相关推荐
用户693717500138412 分钟前
11.Kotlin 类:继承控制的关键 ——final 与 open 修饰符
android·后端·kotlin
用户693717500138415 分钟前
10.Kotlin 类:延迟初始化:lateinit 与 by lazy 的对决
android·后端·kotlin
KotlinKUG贵州27 分钟前
SpringGateway-MVC对SSE转发出现阻塞响应问题的分析和解决
spring·spring cloud·kotlin
zhangphil1 小时前
Android宽高不均等Bitmap缩放为指定宽高FitCenter到正方形Bitmap,Kotlin
android·kotlin
alexhilton13 小时前
深入理解withContext和launch的真正区别
android·kotlin·android jetpack
g***B73819 小时前
Kotlin协程在Android中的使用
android·开发语言·kotlin
A***279519 小时前
Kotlin反射机制
android·开发语言·kotlin
q***d17320 小时前
Kotlin在后台服务中的框架
android·开发语言·kotlin
aqi001 天前
FFmpeg开发笔记(九十一)基于Kotlin的Android直播开源框架RootEncoder
android·ffmpeg·kotlin·音视频·直播·流媒体
来来走走2 天前
Android开发(Kotlin) LiveData的基本了解
android·开发语言·kotlin