美文网首页
kotlin--泛型

kotlin--泛型

作者: aruba | 来源:发表于2021-08-25 10:33 被阅读0次

kotlin作为一种高级语言,也提供了泛型,它的泛型比Java更为灵活

一、泛型类

1.定义泛型类

定义泛型类和Java差不多

class Magic<T>(_item: T) {
    var subOject: T = _item
}

data class Boy(var name: String, var age: Int)

data class Dog(var age: Int)

fun main() {
    println(Magic(Boy("danny", 15)).subOject)
    println(Magic(Dog(15)).subOject)
}

结果:
Boy(name=danny, age=15)
Dog(age=15)

二、泛型函数

1.泛型参数也可以用于函数
class Magic<T>(_item: T) {
    var subOject: T = _item
    var available: Boolean = false

    fun getItem(): T? {
        //available为true,返回泛型类型对象subOject
        return subOject.takeIf { available }
    }
}

data class Boy(var name: String, var age: Int)

fun main() {
    val magic = Magic(Boy("danny", 15))
    magic.available = true
    println(magic.getItem())
}
2.多个泛型参数的函数
class Magic<T>(_item: T) {
    var subOject: T = _item
    var available: Boolean = false

    fun <R> getItem(funp: (T) -> R): R? {
        //available为true,返回泛型类型对象R
        return funp(subOject).takeIf { available }
    }
}

data class Boy(var name: String, var age: Int)

data class Man(var name: String, var age: Int)

fun main() {
    val magic = Magic(Boy("danny", 15))
    magic.available = true
    //boy变成man
    val man = magic.getItem {
        Man(it.name, it.age.plus(10))
    }
    println(man)
}

三、泛型类型约束

1.如果想要对传递的泛型作约束,可以指定泛型的父类
//指定父类
class Magic<T : Human>(_item: T) {
    var subOject: T = _item
    var available: Boolean = false
}

open class Human(var age: Int)
2.如果想要放入多个实例,使用vararg关键字
class Magic<T : Human>(vararg _items: T) {
    var subOject: Array<out T> = _items
    var available: Boolean = false
}
3.使用[]操作符取值,也可以自己重载get函数
class Magic<T : Human>(vararg _items: T) {
    var subOject: Array<out T> = _items
    var available: Boolean = false

    fun <R> getItem(index: Int, funp: (T) -> R): R? {
        if (index > subOject.size - 1) return null

        //available为true,返回泛型类型对象R
        return funp(subOject[index]).takeIf { available }
    }

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

//父类
open class Human(var age: Int)

class Boy(var name: String, _age: Int) : Human(_age)

class Man(var name: String, _age: Int) : Human(_age)

fun main() {
    val magic = Magic(Boy("danny", 15))
    magic.available = true
    //boy变成man
    val man = magic.getItem(0) {
        Man(it.name, it.age.plus(10))
    }
    println("${man?.name} ${man?.age}")
}
4.out

out修饰泛型,表示该泛型对象可以赋值给父类

class Product<out T : Human>(val product: T) {
    fun getItem(): T? = product
}

//父类
open class Human(var age: Int)

class Boy(var name: String, _age: Int) : Human(_age)

class Man(var name: String, _age: Int) : Human(_age)

fun main() {
    //泛型是Human,传入的是Boy,Human的子类
    val boy: Product<Human> = Product(Boy("danny", 15))
    println(boy.getItem())
}

结果:
com.aruba.mykotlinapplication.Boy@3cd1a2f1

5.in

in修饰泛型,表示该泛型对象可以赋值给子类

class Consume<in T : Human>() {
    fun cousume(item: T) {
        println(item)
    }
}

//父类
open class Human(var age: Int)

open class Boy(var name: String, _age: Int) : Human(_age)

class Man(_name: String, _age: Int) : Boy(_name, _age)

fun main() {
    //泛型为Boy类型
    val man: Consume<Boy> = Consume()
    //传入的是Boy的父类Man
    man.cousume(Man("danny", 15))
}

结果:
com.aruba.mykotlinapplication.Man@3cd1a2f1

而Java中泛型只能使用对应的泛型,没有继承关系

6.reified

kotlin也不允许对泛型作类型检查,当我们想要知道泛型参数具体是哪个类型时,可以使用reified关键字修饰
reified必须和inline配合使用,原因是编译的时候,编译器就需要知道我们传入的类型,只不过代码写成了泛型而已

class Magic {
    inline fun <reified T : Human> getBoy(backUp: () -> T): T {
        //随机取一个
        val human = listOf(
            Boy("danny", 15),
            Man("jack", 25)
        ).shuffled().first()

        println(human)
        //如果和backup函数返回参数的类型相同,直接返回
        return if (human is T) {
            human
        } else {//否则返回backup函数调用结果
            backUp()
        }
    }
}

open class Human()

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

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

fun main() {
    val magic = Magic()
    println(magic.getBoy { Boy("danny", 15) })
}

随机到不是Boy型变量的结果:
com.aruba.mykotlinapplication.Man@3f99bd52
com.aruba.mykotlinapplication.Boy@4f023edb
随机到Boy型变量的结果:
com.aruba.mykotlinapplication.Boy@3f99bd52
com.aruba.mykotlinapplication.Boy@3f99bd52

相关文章

  • kotlin--泛型

    kotlin作为一种高级语言,也提供了泛型,它的泛型比Java更为灵活 一、泛型类 1.定义泛型类 定义泛型类和J...

  • 泛型 & 注解 & Log4J日志组件

    掌握的知识 : 基本用法、泛型擦除、泛型类/泛型方法/泛型接口、泛型关键字、反射泛型(案例) 泛型 概述 : 泛型...

  • 【泛型】通配符与嵌套

    上一篇 【泛型】泛型的作用与定义 1 泛型分类 泛型可以分成泛型类、泛型方法和泛型接口 1.1 泛型类 一个泛型类...

  • 泛型的使用

    泛型有三种使用方式,分别为:泛型类、泛型接口、泛型方法 泛型类 泛型接口 泛型通配符 泛型方法 静态方法与...

  • Java 泛型

    泛型类 例如 泛型接口 例如 泛型通配符 泛型方法 类中的泛型方法 泛型方法与可变参数 静态方法与泛型 泛型上下边...

  • 探秘 Java 中的泛型(Generic)

    本文包括:JDK5之前集合对象使用问题泛型的出现泛型应用泛型典型应用自定义泛型——泛型方法自定义泛型——泛型类泛型...

  • Web笔记-基础加强

    泛型高级应用 自定义泛型方法 自定义泛型类 泛型通配符? 泛型的上下限 泛型的定义者和泛型的使用者 泛型的定义者:...

  • 重走安卓进阶路——泛型

    ps.原来的标题 为什么我们需要泛型? 泛型类、泛型接口和泛型方法(泛型类和泛型接口的定义与泛型方法辨析); 如何...

  • Kotlin泛型的高级特性(六)

    泛型的高级特性1、泛型实化2、泛型协变3、泛型逆变 泛型实化 在Java中(JDK1.5之后),泛型功能是通过泛型...

  • Java 19-5.1泛型

    泛型类定义泛型类可以规定传入对象 泛型类 和泛型方法 泛型接口 如果实现类也无法确定泛型 可以在继承类中确定泛型:

网友评论

      本文标题:kotlin--泛型

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