Kotlin系列——泛型型变

本文章已授权微信公众号郭霖(guolin_blog)转载。

本文章讲解的内容是泛型型变,我写一个扩展Boolean示例代码来应用我要讲的内容,示例代码如下:

BooleanExtensionDemo

先看下以下例子,代码如下:

List<String> strings = new ArrayList<String>();
// Java中禁止这样的操作
List<Object> objects = strings;

Java中是禁止这样的操作的,我们看下Kotlin的写法,代码如下:

val strings: List<String> = arrayListOf()
val anys: List<Any> = strings

Kotlin中是允许这样的操作的,这是为什么呢?下面会详细解释。

List中,List基础类型String类型实参,现有两个List集合,分别是ListList,它们都具有相同基础类型,但是类型实参不相同,并且StringAny存在父子关系型变就是指**ListList**这两者存在什么关系。

形式参数和实际参数

函数中的形参和实参

代码如下:

fun add(firstNumber: Int, secondNumber: Int): Int =
    firstNumber + secondNumber

firstNumbersecondNumber就是形式参数,然后去调用这个函数,代码如下:

val first = 1
val second = 2
add(first, second)

firstsecond就是add函数实际参数

泛型中的形参和实参

代码如下:

class Fruit<T>(var item: T)

T就是类型形参,然后使用这个,代码如下:

val fruit = Fruit<Int>(100)

Int就是Fruit类型实参,因为Kotlin具有类型推导特性,不必明确指明类型,所以其实可以写成如下代码:

val fruit = Fruit(100)

在这种情况下,Int依然是Fruit类型实参

还有以下情况,请看代码:

// Collections.kt
public interface MutableList<E> : List<E>, MutableCollection<E> {
   
    // 省略部分代码
}

这里的EListMutableCollection类型实参,同时是MutableList类型形参

结论

定义在里面就是形式参数,定义在外面就是实际参数。

子类、超类、子类型、超类型

子类继承超类,例如class Apple: Fruit()Apple就是Fruit子类Fruit就是Apple超类,那什么是子类型超类型呢?它们的规则比子类超类更加宽松,如果需要A类型的地方,都可以用B类型来代替,那么B类型就是A类型的子类型,A类型就是B类型的超类型,例如StringString?,如果一个函数接收的是String?,我们传入的是String的话,编译器是不会报错的,但是如果一个函数接受的是String,我们传入的是String?的话,编译器就会提示我们可能会存在空指针的问题,所以String就是**String?**的子类型,String?就是String的超类型。

子类型化关系

如果需要A类型的地方,都可以用B类型来代替,那么B类型就是A类型的子类型,B类型到A类型之间的映射关系就是子类型化关系,举个例子:ListList子类型,所以ListList之间存在子类型化关系ListList<String?>子类型,所以ListList<String?>之间存在子类型化关系,**MutableListMutableList**之间就没有关系,这个会在下面解释。

协变

协变(convariant)就是保留子类型化关系保证泛型内部操作该类型时是只读的,在Java中,带extends限定(上界)通配符类型使得类型是协变的。

因为List协变StringAny子类型StringString?子类型,所以ListList子类型ListList<String?>子类型

out协变点

以下代码是标准out协变点

// T被声明为out
interface Producer<out T> {
   

    // T作为只读属性的类型
    val value: T

    // T作为函数返回值的类型
    fun produce(): T

    // T作为只
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值