泛型类 泛型接口 泛型方法 泛型约束 out T 协变 in T 逆变

泛型类的定义:

泛型类都是有主构造函数的,其主构造函数可以接受任何类型。

 只需要在泛型类的后面加上<> 即可,里面定义泛型 T、M、K 等等

//定义一个泛型T
class Generate<T>(var t:T)
//定义多个泛型T  K
class GenerateMore<T,K>(val t:T,val k:K)

泛型接口的定义:

在名字后面加 <>

//该接口定义一个泛型T
interface GenerateInter<T>{
     //使用传过来的泛型
     fun useT(t:T)
}

//该接口定义多个泛型T  M
interface GenerateInterMore<T,M>{
     //使用传过来的泛型
     fun useT(t:T)
     //使用传过来的多个泛型
     fun useTM(t:T,m:M)
}

泛型方法的定义:

泛型方法的参数可以用泛型T表示。

//该方法定义一个泛型T
fun <T> generate(t:T){
     println()
}
//该方法定义多个泛型T L
fun <T,L> generateMore(t:T,l:L){
     
}

多泛型参数:

泛型类 泛型函数 可以有多个不同 的泛型参数  

泛型类型T的约束:

让未知的泛型T 子类  继承某个父类类型,让泛型子类T的范围被约束缩小。

vararg 关键字 :可以表示多个泛型参数

 多个泛型参数 vararg item: T 最终表示的是一个集合

  var subject: Array<out T> = item

如果我想要获取多个泛型集合subject里的某一个具体的泛型数据T

operator  fun get(index: Int):T?=subject[index].takeIf { available }
fun fetch(index: Int): T? { return subject[index].takeIf { available }}

  



/**
 *T : Human  表示对泛型T的类型约束:T指定的类型只能是继承Human的子类
 * */
class MagicBox<T : Human>(vararg item: T) {
    var available = false
    private var subject: Array<out T> = item

    operator  fun get(index: Int):T?=subject[index].takeIf { available }

    fun fetch(index: Int): T? {
        return subject[index].takeIf { available }
    }

    //业务,把元素进行修改
    //魔盒里面放的是男孩,取出来的时候,我给他改成了一个男人
    //return -> R
    /**
     * 多泛型参数:泛型函数或泛型类可以有多个泛型参数。
     * */
    fun <R> fetch(index: Int, subjectModFunction: (T) -> R): R? {
        return subjectModFunction(subject[index]).takeIf { available }
    }
}

open class Human(val age: Int)

class Boy(val name: String, age: Int) : Human(age)

class Man(val name: String, age: Int) : Human(age)

class Dog(val weight: Int)

fun main() {
    val box1: MagicBox<Boy> = MagicBox(
        Boy("Jack", 15),
        Boy("Jacky", 16),
        Boy("John", 26)
    )
    box1.available = true

    box1.fetch(0)?.run { println("you find $name") }
    
    val man0  =  box1.fetch(1)
      man0?.run {  println("当前的具体泛型数据是: ${name+age}") } //当前的具体泛型数据是: Jacky 16

     
    box1.get(2)?.run { println("当前的具体泛型数据是: ${name+age}") } //当前的具体泛型数据是: John 26


     val man = box1.fetch(2, subjectModFunction={its-> Man(its.name, its.age.plus(15))})
    

}

out T  协变

泛型类 将泛型类型T 作为泛型函数数据的返回,使用out T 。主要用来生产泛型数据T对象的

private var subject: Array<out T> = item

interface Production<out T>{  public fun product():T     }

  in  T  逆变 

 泛型类 只是将泛型类型T,作为泛型函数的入参参数。主要用来消费使用 泛型对象T的

 interface Consumer<in T>{

  fun consume(item:T)

}

invariant 不变   泛型类 即将泛型T 作为泛型函数的数据返回(生产泛型数据T),又作为泛型函数的入参参数(消费使用 泛型对象T)

  interface ProductionConsumer<T>{

   fun product():T //返回泛型数据T 生产者

 fun  consume(item:T)    //泛型数据T 作为参数,消费使用泛型数据T 

}

为什么要使用in&out?

  父类泛型对象转成子类泛型对象  in     

   子类泛型对象 转成父类泛型对象  out 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值