【2025最新版Kotlin教程】Kotlin第一行代码系列第十课-泛型T

80 阅读2分钟
【2025最新版Kotlin教程】Kotlin第一行代码系列第十课-泛型T

泛型:可为泛型? 泛型就是对程序的抽象,也可以认为就对类的抽象 用个符号来声明先,到时你生成对象时,传什么对象来,就是什么

泛型有:泛型类,泛型方法,泛型属性

使用场景:底层封装。把相同的东西抽离出来,做出泛型

下面看个Android开发中的例子

  // 源码联系:893151960
  abstract class BaseActivity<VB : ViewBinding, VM : BViewModel> : AppCompatActivity(){}
  • 注意:不一定是写T的,写任何字母都行
一、泛型类
// 方式1 最简单的
// T R
class Test<T>{
     var name:T? = null
    fun walk(name: T) {
        println("${name}走路")
    }
}

// 方式2 这个复杂些
class MagicBox<T>(val item: T) {
    var available = false

    fun fetch(): T? {
        return item.takeIf { available }
    }

    /**
     * 函数中增加范式类型,类似Java
     */
    fun <R> fetch(anotherGenericity: (T) -> R): R? {
        return anotherGenericity(item).takeIf { available }
    }
}

private class Bird(val name: String)

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

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

fun main() {

    val test = Test<String>()
    //只能传字符串了
    test.walk("nihao")

    val boy = MagicBox(Boy("Jim", 16))
    val bird = MagicBox(Bird("啄木鸟"))
    boy.available = true

    boy.fetch()?.run {
        println("find a boy.name:${name},age:${age}")
    }

    val man = boy.fetch {
        Man(it.name, it.age.plus(10))
    }
    man?.run {
        println("find a boy.name:${name},age:${age}")
    }
}
二、约束泛型

指定泛型是属于某个类型的,T:Human 限制为它或者它的子类

//定义一个约束泛型
private class ConstraintMagicBox<T:Human>(item:T){

}

//定义一个父类
private open class Human(val name: String,val age:Int)
//定义一个Human类的子类
private class Male(name: String,age: Int):Human(name, age)
//定义一个Human类的子类
private class Female(name: String,age: Int):Human(name, age)

fun main() {
    //同为Human类型的可传入
    val male = ConstraintMagicBox(Male("Jack", 20))
    val female = ConstraintMagicBox(Female("Jim", 20))
    val male1 = ConstraintMagicBox(Human("JackFather", 20))
}
三、用in、out修饰泛型
//out修饰的泛型 仅将泛型作为函数返回值
//作用:让子类泛型对象可以赋值给父类泛型对象
// T extend XXClac
interface OutTest<out T>{
    fun outTest():T
}

//in修饰的泛型 仅将泛型作为函数参数,泛型无法当做返回值
//作用:让父类泛型对象可以赋值给子类泛型对象
interface InTest<in T>{
    fun inTest(param : T)
}

//泛型无修饰时,可作为函数参数和函数返回类型
interface NoneTest<T>{
    fun none1(param : T)
    fun none2():T
}

open class Food()

open class FastFood():Food()

class Hamburg():FastFood()

class FastFoodStore() : OutTest<FastFood>{
    override fun outTest(): FastFood {
        println("FastFoodStore ----------")
        return FastFood()
    }
}

class HamburgStore():InTest<FastFood>{
    override fun inTest(param: FastFood) {
        println("HamburgStore-----------")
    }

}

fun main() {
    //子类对象可以传给父类泛型对象 out
    // T extend
    val food1 : OutTest<Food> = FastFoodStore()

    //父类对象可以传给子类泛型对象 in
    val food2 : InTest<Hamburg> = HamburgStore()
}
整个kotlin教程项目源码结构图:

在这里插入图片描述
有问题或者完整源码的可以看简介联系我,也可以私信我,我每天都看私信的