美文网首页
Kotlin之泛型

Kotlin之泛型

作者: Deck方 | 来源:发表于2023-07-06 21:46 被阅读0次

    一、泛型类

    class MagicBox<T>(item:T){
        private var subject:T =item
    }
    
    class Boy(val name:String,val age:Int)
    class Dog(val weight:Float)
    
    fun  main(){
        var magicBoxBoy:MagicBox<Boy> = MagicBox(Boy("Jack", 28))
        var magicBoxDog:MagicBox<Dog> = MagicBox(Dog(20f))
    }
    

    二、泛型函数

    class MagicBox<T>(item: T) {
    
        var available = false
        private var subject: T = item
    
        fun fetch(): T? {
            return subject.takeIf {
                available
            }
        }
    
    }
    
    class Boy(val name: String, val age: Int)
    class Dog(val weight: Float)
    
    fun main() {
        var magicBoxBoy: MagicBox<Boy> = MagicBox(Boy("Jack", 28))
        var magicBoxDog: MagicBox<Dog> = MagicBox(Dog(20f ))
        magicBoxBoy.available=true
         magicBoxBoy.fetch()?.run {
             println("$name")
         }
    } 
    

    三、多泛型参数

    class MagicBox<T>(item: T) {
    var available = false
        private var subject: T = item
    
        fun <R> fetch(subjectModFunction: (T) -> R): R? {
            return subjectModFunction(subject).takeIf { available }
        }
    }
    

    四、泛型类型的约束

    声明T类型是Human的子类

    class MagicBox<T:Human>(item: T) {
    
        var available = false
        private var subject: T = item
    
        fun <R> fetch(subjectModFunction: (T) -> R): R? {
            return subjectModFunction(subject).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: Float)
    
    fun main() {
        var magicBoxBoy: MagicBox<Boy> = MagicBox(Boy("Jack", 28))
    //    var magicBoxDog: MagicBox<Dog> = MagicBox(Dog( 20))
    }
    

    五、out(协变)和in(逆变)

    1.out(协变),如果泛型类只将泛型类型作为函数的返回(输出),那么使用out,可以称之为生产类/接口,因为它主要是用来生产(produce)指定的泛型对象。

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

    2.in(逆变),如果泛型类只将泛型类型作为函数的入参(输入),那么使用in,可以称之为消费者类/接口,因为它主要是用来消费(consume)指定的泛型对象。

    interface Consumer<in T> {
        fun consume(item: T)
    }
    

    3.(不变)如果泛型类既将泛型类型作为函数参数,又将泛型类型作为函数的输出,那么既不用out也不用in

    4.父类泛型对象可以赋值给子类泛型对象,使用in;子类泛型对象可以赋值给父类泛型对象,使用out

    interface ProductionConsumer<T>{
        fun product():T
        fun consume(item:T)
    }
    interface Production<out T> {
        fun product(): T
    }
    open class Food()
    open class FastFood : Food()
    class Hamburger : FastFood()
    class FoodStore:Production<Food>{
        override fun product(): Food {
            return Food()
        }
    }
    
    class FastFoodStore :Production<FastFood>{
        override fun product(): FastFood {
            return FastFood()
        }
    }
    class HamburgerStore:Production<Hamburger>{
        override fun product(): Hamburger {
            return Hamburger()
        }
    }
    
    
    
    
    class EveryBody:Consumer<Food>{
        override fun consume(item: Food) {
            println("eat food")
        }
    }
    
    class ModernPeople:Consumer<FastFood>{
        override fun consume(item: FastFood) {
            println("eat fastFood")
        }
    }
    
    class American:Consumer<Hamburger>{
        override fun consume(item: Hamburger) {
            println("eat hamburger")
        }
    }
    fun main() {
    
       val food: Production<Food> = FoodStore()
        //变量的类型声明中使用了父类类型,这java中这样赋值会有编译错误,但是kotlin中通过out实现了
    //子类泛型对象可以赋值给父类泛型对象,使用out
       val fastFood: Production<Food> = FastFoodStore()
    
    //父类泛型对象可以赋值给子类泛型对象,使用in
        val consumer :Consumer<Hamburger> = EveryBody()
    }
    

    六、reified

    class MagicBox<T : Human>(item: T) {
    //    fun <T> randomOrBackup(backup: () -> T): T {
    //        val list = listOf(Boy("Jack", 28), Man("Bob", 24))
    //        val random = list.shuffled().first()
    //        return if (random is T) {
    //            random
    //        } else {
    //            backup()
    //        }
    //    }
    
    //reified 配合inline关键字
       inline fun <reified T> randomOrBackup(backup: () -> T): T {
            val list = listOf(Boy("Jack", 28), Man("Bob", 24))
            val random = list.shuffled().first()
            return if (random is T) {
                random
            } else {
                backup()
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:Kotlin之泛型

          本文链接:https://www.haomeiwen.com/subject/ocmludtx.html