朱涛 · Kotlin 编程第一课
朱涛
Google 认证的 Kotlin、Android 开发者专家,博客“Kotlin Jetpack 实战”作者
6717 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 50 讲
朱涛 · Kotlin 编程第一课
15
15
1.0x
00:00/00:00
登录|注册

09 | 委托:你为何总是被低估?

你好,我是朱涛。今天我们来学习 Kotlin 的委托特性。
Kotlin 的委托主要有两个应用场景,一个是委托类,另一个是委托属性。对比第 6 讲我们学过的扩展来看的话,Kotlin 委托这个特性就没有那么“神奇”了。
因为扩展可以从类的外部,为一个类“添加”成员方法和属性,因此 Kotlin 扩展的应用场景也十分明确,而 Kotlin 委托的应用场景就没那么清晰了。这也是很多人会“重视扩展”,而“轻视委托”的原因。
然而,我要告诉你的是,Kotlin“委托”的重要性一点也不比“扩展”低。Kotlin 委托在软件架构中可以发挥巨大的作用,在掌握了 Kotlin 委托特性后,你不仅可以改善应用的架构,还可以大大提升开发效率。
另外,如果你是 Android 工程师,你会发现 Jetpack Compose 当中大量使用了 Kotlin 委托特性。可以说,如果你不理解委托,你就无法真正理解 Jetpack Compose。
看到这里,想必你也已经知道 Kotlin 委托的重要性了,接下来就来开启我们的学习之旅吧!

委托类

我们先从委托类开始,它的使用场景非常简单易懂:它常常用于实现类的“委托模式”。我们来看个简单例子:
interface DB {
fun save()
}
class SqlDB() : DB {
override fun save() { println("save to sql") }
}
class GreenDaoDB() : DB {
override fun save() { println("save to GreenDao") }
}
// 参数 通过 by 将接口实现委托给 db
// ↓ ↓
class UniversalDB(db: DB) : DB by db
fun main() {
UniversalDB(SqlDB()).save()
UniversalDB(GreenDaoDB()).save()
}
/*
输出:
save to sql
save to GreenDao
*/
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Kotlin委托特性在软件架构中扮演着重要角色,通过委托模式简化代码,提高开发效率。委托属性和委托类的灵活运用,能够实现属性之间的直接委托和懒加载委托,提高软件版本兼容性和避免资源开销。文章介绍了自定义委托的方法,以及在Android应用中的实际案例。此外,还探讨了ViewModel委托的实现原理,展示了Kotlin委托的强大功能和灵活运用。总的来说,本文通过深入讲解Kotlin委托的基本概念和高级应用,为读者提供了全面的了解和实践指导。文章内容丰富,涵盖了委托语法的多种使用场景,对读者的技术启发和应用提供了有力支持。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《朱涛 · Kotlin 编程第一课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(20)

  • 最新
  • 精选
  • ZircoN
    SP读写的委托封装,经常用

    作者回复: 没错,这也是一个比较常见的应用场景。另外,针对这样的委托封装,我们在变量命名的时候,最好是可以跟普通变量区分开。

    2022-01-30
    7
  • 文茂权
    给没看懂自定义委托的同学做点笔记: kotlin.properties.PropertyDelegateProvider 接口:可以用于属性委托的基本接口,但开发者可以直接 override fun 而不声明实现。 在这里 SmartDelegator 是直接实现了provideDelegate 方法,(隐式实现了这个接口),所以可以直接对 Owner 提供委托的实现。

    作者回复: 赞~很好的补充。

    2022-01-17
    6
  • 7Promise
    Kotlin 委托的使用场景:列表控件的适配器对象可以通过懒加载(by lazy)获得。可以待数据获取成功时才使用该适配器对象,从而避免不需要的时候创建该对象。

    作者回复: 不错~理解到位。

    2022-01-17
    2
    4
  • A Lonely Cat
    只要你暴露了集合的实例给外部,外部就可以随意修改集合的值。 实现了 List 接口的集合类如果没有实现某些方法,外部调用时就会抛出 UnsupportedOperationException 这个异常,Arrays.ArrayList 这个内部类就没有实现 List 接口的某些方法,所以外部在调用这些方法时就会抛出异常,也就无法随意修改集合的值了。

    作者回复: 感谢你提出了一个这么有深度的问题。我那句话的语境,其实是Java当中的java.util.ArrayList实例暴露出去以后,肯定就能随意修改了。 当然,我知道你的意思。我们可以将其转换成Java里特殊的类型,比如:你提到的Arrays.ArrayList、还有SingletonList或者是自定义的集合。但这种做法终归是不优雅的,因为调用方不知情的话,是会抛出UnsupportedOperationException导致崩溃的。 关于这一点,我在后面的加餐当中也有讨论,到时候我们可以一起交流~

    2022-01-21
    2
    2
  • 白乾涛
    设计的太复杂了,这么复杂的语法肯定劝退了好多人

    作者回复: 是的,语法确实看起来太吓人了。

    2022-01-19
    2
  • 叶稳健
    @NotNull public final String getName() { Map var1 = this.name$delegate; KProperty var3 = $$delegatedProperties[0]; boolean var4 = false; return (String)MapsKt.getOrImplicitDefaultNullable(var1, var3.getName()); } 您好,我尝试将 kotlin 编译后的 class 反编译为 java 文件来学习 by map 委托的原理,但是 MapsKt.getOrImplicitDefaultNullable 这个方法我为何找不到?MapsKt 类可以在 Kotlin 的开源库内找到,该方法实现却没有,望帮忙解答,谢谢

    作者回复: 这个的实现在Kotlin的源码里面,你去GitHub下载Kotlin的工程,导入IDE就能找到了: ``` // 对应 JVM 的 getOrImplicitDefaultNullable internal fun <K, V> Map<K, V>.getOrImplicitDefault(key: K): V { if (this is MapWithDefault) return this.getOrImplicitDefault(key) return getOrElseNullable(key, { throw NoSuchElementException("Key $key is missing in the map.") }) } ```

    2022-04-29
    1
  • l-zesong
    现在手机内存这么大,by lazy有必要吗?

    作者回复: 这个其实就是见仁见智了。我个人的看法就是:如果要费很大力气去实现某个变量的懒加载的话,可能得不偿失;但如果是简单一个by lazy就能实现的话,也没太高的成本。

    2022-01-24
    3
    1
  • 杨浩
    java很容易就上手,基本语法很少。 感觉kotlin,把很多的设计模式都变成了语法,很强大,同时也很深奥。

    作者回复: 是啊,表面上越简单的东西,底层就越复杂。

    2022-01-22
    2
    1
  • 曾帅
    委托,或者说代理,开发中比较常见的还有 mock 数据,主界面版本的迭代,开源框架的功能包裹。感觉这些概念还是一样,只是 Kotlin 让这些东西写起来更加简单,或者更加方便。

    作者回复: 说的很好,赞~

    2022-01-20
    1
  • H.ZWei
    var total: Int by ::count 报错:Type KMutableProperty0 has no method getValue/setValue and thus it cannot serve as a delegate kotlin是1.6版本,IDE是intelliJ 2021.3版本的

    作者回复: 会不会是导包有问题?你在Kotlin的在线环境运行试试:https://play.kotlinlang.org/

    2022-03-20
收起评论
显示
设置
留言
20
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部