通过 AbstractCoroutineContextElement 更加深入理解 Kotlin 伴生对象

通过 AbstractCoroutineContextElement 更加深入理解 Kotlin 伴生对象

​ 最近疫情居家办公,没事摸鱼在看《深入理解 Kotlin 协程》这本书,发现 Kotlin 协程上下文需要添加元素时会用到 AbstractCoroutineContextElement 这个类。书中案例代码如下:

class CoroutineName(val name: String): AbstractCoroutineContextElement(Key){
    companion object Key: CoroutineContext.Key<CoroutineName> // 1
}
var coroutineContext = CoroutineName("co-01")
val test = suspend { 
    ....
}.startCoroutine(object : Continuation<Unit>{
    override val context: CoroutineContext
        get() = coroutineContext

    override fun resumeWith(result: Result<Unit>) {
        println(context[CoroutineName]) // 2
    }
})

​ 可能由于我的基础并不是很好,我在看 1 号位置的伴生对象时,竟然误以为定义了一个伴生对象的 Key 属性,该Key的类型为 CoroutineContext.Key<CoroutineName> 以至于后面我无法理解 2 号位置的代码(不知道有没有小伙伴和我一样😂)。

​ 而正确的理解是 1 号代码位置的 Key 是 CoroutineName 类的伴生对象,该对象实现了CoroutineContext.Key<CoroutineName> 接口,因为该接口没有需要实现的方法,所以是一个空实现。而2号位置的代码直接使用了 CoroutineName 类名。一开始我以为是有 CoroutineName 的字段,但是根本没有。我又去翻看了 《Kotlin 核心编程》中关于伴生对象的这块的描述。结合以下例子,才发现这里的 CoroutineName 也是 CoroutineName 类的伴生对象。


open class Shu{
    companion object{ //未命名的伴生对象,在外部仍然可以使用 [类名.属性名] 调用伴生对象内的属性
        val name = "nihao"
    }

    override fun toString(): String {
        return name
    }
}
class NO3 {
    companion object Yang : Shu() //命名过的伴生对象,并且继承字Shu类,没有字段
    fun test():String{
        println(Yang.toString()) //内部可以直接通过伴生对象名调用
        println(NO3.toString()) //也可以直接通过类名调用
        return Shu.name
//        return Yang.name  //不可调用
}
fun main() {
    println(Shu.name)
    println(NO3)
}
>>> nihao
>>> nihao

通过上面的例子就很明了了

  1. 伴生对象一个类中只能有一个
  2. 伴生对象也是对象,可以继承
  3. 伴生对象可以有名字
  4. 如果其他地方直接使用某个类的类名作为参数,那么这个类名不是指代该类,而是该类的伴生对象
  5. 和类的静态成员一样,伴生对象子类肯定也不可以被子类继承
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值