泛型

定义泛型类

  • 语法结构

    1
    2
    3
    4
    5
    6
    //T代指泛型是一种约定俗成
    class MyClass<T> {
    fun method(param:T):T{
    return param
    }
    }
  • 调用

    1
    2
    3
    val myClass=MyClass<Int>()
    val result=myClass.method(123)
    println(result)

定义泛型方法

  • 语法结构

    1
    2
    3
    4
    5
    class MyClass{
    fun<T>method(param:T):T{
    return param
    }
    }
  • 调用

    1
    2
    3
    val myClass=MyClass()
    val result=myClass.method<Int>(123)
    println(result)

泛型上界

对泛型类型进行限制

  • 语法结构

    1
    2
    3
    4
    5
    class MyClass{
    fun<T:Number>method(param:T):T{
    return param
    }
    }
  • 调用

    1
    2
    3
    val myClass=MyClass()
    val result=myClass.method(123)
    println(result)

类委托和委托属性

类委托

  • 原理

    将一个类的具体实现委托给另一个类去完成

  • 意义

    大部分方法实现调用辅助对象的方法,少部分方法实现自己重写,甚至加入自己独有的方法

  • 实例

    MySet构造函数中接收了一个HashSet参数这就相当于一个辅助对象,Set接口中所有方法的实现都是调用了辅助对象中相应的方法实现的,这就是类委托

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class MySet<T>(val helperSet: HashSet<T>) : Set<T>  {
    override val size: Int
    get() = helperSet.size
    override fun isEmpty()=helperSet.isEmpty()

    override fun iterator()=helperSet.iterator()

    override fun containsAll(elements: Collection<T>)=helperSet.containsAll(elements)

    override fun contains(element: T)=helperSet.contains(element)
    }

    使用by类委托关键字简化

    哪个方法需要重新实现只需要写那一个方法即可,不需要把所有继承方法都写下来

    1
    2
    3
    4
    5
    6
    7
    class MySet<T>(val helperSet: HashSet<T>) : Set<T> by helperSet {

    fun helloWorld() = println("Hello World")

    override fun isEmpty() = false

    }

委托属性

  • 原理

    将一个属性(字段)的具体实现委托给另一个类去完成

  • 语法结构

    将p属性具体实现委托给Delegate类完成,当调用p时会自动调用Delegate的getValue()方法,当给其赋值会调用Delegate的setValue()方法

    1
    2
    3
    class MyClass{
    var p by Delegate()
    }

    Delegate()的实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    class Delegate {

    var propValue: Any? = null

    /**
    * 第一个参数声明该委托功能可以在哪个类中使用
    第二个参数是一个属性操作类,当前情景用不着但必须声明
    */
    operator fun getValue(myClass: MyClass, prop: KProperty<*>): Any? {
    return propValue
    }
    /**
    * 第一个参数声明该委托功能可以在哪个类中使用
    第二个参数是一个属性操作类,当前情景用不着但必须声明
    第三个参数表示具体赋给委托属性的值,必须与getValue方法返回值类型一致
    */
    operator fun setValue(myClass: MyClass, prop: KProperty<*>, value: Any?) {
    propValue = value
    }

    }

    **注意:**当p属性用val修饰时不需要再去实现setValue方法


实现一个自己的lazy函数

  • 高阶函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Later<T>(val block:()->T){
    var value:Any?=null
    operator fun getValue(any:Any?,prop:KProperty<*>):T{
    if(value==null){
    value=block()
    }
    return value as T
    }
    }
  • 创建Later类实例并将接收的函数类型参数传给Later类的构造函数

    1
    fun <T>later(block:()->T)=Later(block)
  • 实现

    1
    2
    3
    4
    5
    6
    val uriMatcher by later{
    val matcher=UriMatcher(UriMatcher.NO_MATCH)
    matcher.addURI(authority,path,CODE_CREATE)
    ......
    matcher
    }
  • 验证

    1
    2
    3
    4
    val p by later{
    Log.d("TAG","run codes inside later block")
    "test later"
    }

    注意:一般还是更常用Kotlin内置的lazy函数