• Kotlin(十四)泛型


    1.泛型类、泛型函数

      1)泛型类可以接收任意类型。Package(t: T)

       2)泛型类中定义的泛型参数,通常用T(Type)表示,(t: T) 这个表示泛型类Package的主构造函数可以接收T类型的属性。

       3)openPackage(): T定义一个返回T类型的泛型函数。

      4)fun getProductName(block: (T) -> R): R  getProductName的返回值是R(英文的Return),接收一个匿名函数为参数block: (T) -> R,这个匿名函数的参数是T,返回值是R。也就是说,匿名函数的返回值,就是getProductName的返回值。这个和前面讲到的apply、let、run、with等是一样的多参数函数。

    1. //泛型类
    2. class Package<T>(t: T) {
    3. private val product: T = t
    4. //泛型函数
    5. fun openPackage(): T {
    6. return product
    7. }
    8. //多参数泛型函数
    9. fun getProductName(block: (T) -> R): R {
    10. return block(product)
    11. }
    12. }
    1. fun main() {
    2. val pkg = Package(Phone("IPhone"))
    3. println(pkg.openPackage())
    4. println(pkg.getProductName {
    5. it.name
    6. })
    7. val pkg2 = Package(Fruit("Apple"))
    8. println(pkg2.openPackage())
    9. println(pkg2.getProductName {
    10. it.name
    11. })
    12. }

     

    2.泛型类型约束。上面的泛型类,可以接收任意类型。如果我们只想某个类接收特定类型的,可以使用泛型约束。

     1)定义一个父类Fruit和两个子类,Apple和Banana

    1. open class Fruit(val name:String){
    2. }
    3. class Apple(name:String) : Fruit(name){
    4. }
    5. class Banana(name:String):Fruit(name){
    6. }

    2)定义泛型类约束: 表示只能接收Fruit类或子类。和Java中的作用是一样的。

     Kotlin中定义泛型约束

    1. class Package<T:Fruit>(t: T) {
    2. private val product: T = t
    3. fun openPackage(): T {
    4. return product
    5. }
    6. fun getProductName(block: (T) -> R): R {
    7. return block(product)
    8. }
    9. }
    10. fun main() {
    11. //定义了泛型约束的类,只能放Fruit的子类
    12. val pkg = Package(Apple("apple"))
    13. val pkg2 = Package(Banana("banana"))
    14. //Phone类型是放不进去的
    15. val pkg3 = Package(Phone("Iphone"))
    16. }

     Java中定义泛型约束

    1. public class Package extends Fruit> {
    2. public T t;
    3. public Package(T t) {
    4. this.t = t;
    5. }
    6. public T openPackage() {
    7. return t;
    8. }
    9. }

    3.泛型类接收的参数也可以是一个集合:

    1. class Package<T:Fruit>(list:List) {
    2. var list = list
    3. fun get(index:Int):Fruit = list[index]
    4. }

     vararg items: T 就表示可以存放多个。vararg就是对应java中的可变参数。可以用一个数组来接收它 Array ,这里的out 就是协变的意思。表示,可以就收该类或该类的子类。

    1. class Package<T : Fruit>(vararg items: T) {
    2. var itmes: Array<out T> = items
    3. operator fun get(index: Int): Fruit = itmes[index]
    4. }
    1. fun main() {
    2. val p = Package22(listOf(Apple("apple")))
    3. println(p.get(0))
    4. val p2 = Package(Apple("apple"))
    5. println(p2[0])
    6. }

     4.协变out,逆变in

       out T 对应java中的 ?extend T

       int T 对应java中的?super T

    5.类型擦除

     对应java和Kotlin,泛型都值存在于编译期,运行后,就不存在泛型的概念,而是指定类型。

    如果我们想要检查所传入泛型的类型,在kotlin中可以使用reified 关键字。在Java中可以通过反射的方式,来获取泛型的类型。

  • 相关阅读:
    Hadoop相关
    基于springboot+vue 农业资源管理系统java
    Flutter高仿微信-第38篇-单聊-转账
    Educational Codeforces Round 32 G. Xor-MST 启发式合并字典树、Boruvka求最小生成树 + 最小异或字典树、分治
    数据库迁移前后密码的读取方式不同导致识别到密码是错的
    【Flink】第二节 windows下运行
    javaScript:键盘事件和表单事件以及鼠标键盘结合事件
    SpringCloud原生组件之Eureka服务注册中心
    LeetCode·20.有效的括号·栈模拟
    jest在已有项目中的安装与使用
  • 原文地址:https://blog.csdn.net/niuyongzhi/article/details/126658067