Kotlin泛型和委托

泛型

//实现类似apply函数功能
//Any表示泛型具体的类型上限
fun <T : Any> T.build(block: T.() -> Unit): T {
    block()
    return this
}

fun main() {
    val sb = StringBuilder()
    sb.build {
        append("123")
        append("wechat")
    }
    println(sb) //123wechat
}

泛型实化

//需要同时使用inline(内联函数)和reified关键字
//直接返回当前指定泛型的实际类型T::class:java
inline fun <reified T> getGenericType() = T::class.java

//应用: 重写startActivity函数
//startActivity<myActivity>(context) { putExtra("param1", "data") }
inline fun <reified T> startActivity(
    context: Context,
    block: Intent.() -> Unit
) {
    val intent = Intent(context, T::class.java)
    intent.block()
    context.startActivity(intent)
}

fun main() {
    println(getGenericType<String>())
    //class java.lang.String
    println(getGenericType<Int>())
    //class java.lang.Integer
}

类委托和委托属性

委托是一种设计模式,它的基本理念是:操作对象自己不会去处理某段逻辑,而是会把工作委托给另外一个辅助对象去处理。

类委托

将一个类的具体实现委托给另一个类去完成。例如,利用helperSet对象去实现MySet类中的功能:

class MySet<T>(val helperSet: HashSet<T>) : Set<T> {
    override val size: Int
        get() = helperSet.size

    override fun contains(element: T) = helperSet.contains(element)
    override fun containsAll(elements: Collection<T>) = helperSet.containsAll(elements)
    override fun isEmpty() = helperSet.isEmpty()
    override fun iterator() = helperSet.iterator()
}

使用场景:让大部分的方法实现调用辅助对象中的方法,少部分的方法实现由自己来重写,甚至加入一些自己独有的方法,那么MySet就会成为一个全新的数据结构类,这就是委托模式的意义所在。 语法糖: Kotlin中委托使用的关键字是by,我们只需要在接口声明的后面使用by关键字,再接上受委托的辅助对象,就可以免去之前所写的一大堆模板式的代码了。如果我们要对某个方法进行重新实现,只需要单独重写那一个方法就可以了,其他的方法仍然可以享受类委托所带来的便利。 MySet就成为了一个全新的数据结构类,它不仅拥有HashSet的全部功能,而且还能打印helloWorld(),这就是Kotlin的类委托所能实现的功能。

class MySet<T>(val helperSet: HashSet<T>) : Set<T> by helperSet {
    fun helloWorld() = println("hello world")
}

属性委托

类委托的核心思想是将一个类的具体实现委托给另一个类去完成,而委托属性的核心思想是将一个属性(字段)的具体实现委托给另一个类去完成。

class MyClass {
    //表示将p属性实现交给Delegate类完成
    //x = p 会自动调用Delegate类中的getValue()方法
    //p = x 会自动调用Delegate类中的setValue()方法
    var p by Delegate()
}

class Delegate {
    var propValue: Any? = null

    //第一个参数表示可以在什么类中使用委托功能
    //KProperty<*>是Kotlin中的一个属性操作类,
    //可用于获取各种属性相关的值,
    //在当前场景下用不着,但是必须在方法参数上进行声明。
    //<*>表示不知道或者不关心泛型的具体类型,只是为了通过编译
    operator fun getValue(myClass: MyClass, kprop: KProperty<*>): Any? {
        return propValue
    }

    operator fun setValue(myClass: MyClass, kprop: KProperty<*>, value: Any?) {
        propValue = value
    }
}
实现lazy懒加载函数

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
    }
}

fun <T> later(block: () -> T) = Later(block)

fun main() {
    //lambda函数只会执行一次
    val p by later { "later string" }
    println(p)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值