首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

Kotlin 委托与扩展函数——新手入门

  • 25-04-17 10:20
  • 2769
  • 5388
juejin.cn

一、委托(Delegation)

1. 类委托

类委托允许将接口的实现委托给另一个对象,避免继承的局限性,适用于组合模式。

示例代码:

kotlin
代码解读
复制代码
interface Printer { fun printMessage(message: String) } class ConsolePrinter : Printer { override fun printMessage(message: String) { println("控制台输出: $message") } } // 通过委托将Printer接口的实现交给ConsolePrinter class LogPrinter(printer: Printer) : Printer by printer { override fun printMessage(message: String) { println("日志记录开始") printer.printMessage(message) println("日志记录结束") } } fun main() { val consolePrinter = ConsolePrinter() val logPrinter = LogPrinter(consolePrinter) logPrinter.printMessage("测试消息") }

使用场景:

  • 需要增强或修改现有类的行为(装饰器模式)。
  • 避免多层继承带来的复杂性。

2. 属性委托

属性委托将属性的 getter/setter 逻辑委托给其他对象,Kotlin 标准库提供多种内置委托。

常用内置委托:

  • lazy:延迟初始化属性。
  • observable:监听属性变化。
  • vetoable:在赋值前验证值。

示例代码:

kotlin
代码解读
复制代码
import kotlin.properties.Delegates class Example { // 延迟初始化,首次访问时计算 val lazyValue: String by lazy { println("计算lazyValue") "Hello, Lazy!" } // 监听属性变化 var name: String by Delegates.observable("<未命名>") { _, old, new -> println("名称从 $old 更改为 $new") } // 仅允许非负数值 var age: Int by Delegates.vetoable(0) { _, _, new -> new >= 0 } } fun main() { val example = Example() println(example.lazyValue) // 输出:计算lazyValue \n Hello, Lazy! example.name = "Kotlin" // 输出:名称从 <未命名> 更改为 Kotlin example.age = -5 // 赋值失败,age保持0 println(example.age) // 输出:0 }

使用场景:

  • lazy:初始化成本高的资源(如数据库连接)。
  • observable:实现数据绑定或响应式UI更新。
  • vetoable:表单输入验证。

3. 自定义属性委托

通过实现 ReadWriteProperty 或 ReadOnlyProperty 接口创建自定义委托。

示例代码:

kotlin
代码解读
复制代码
import kotlin.reflect.KProperty class FormatDelegate(private val format: String) : ReadWriteProperty { private var value: String = "" override fun getValue(thisRef: Any?, property: KProperty<*>): String { return value.format(format) } override fun setValue(thisRef: Any?, property: KProperty<*>, value: String) { this.value = value } } class User { var username: String by FormatDelegate("用户名:%s") } fun main() { val user = User() user.username = "Alice" println(user.username) // 输出:用户名:Alice }

使用场景:

  • 统一格式化字符串、数值等属性。
  • 自动加密/解密敏感数据字段。

二、扩展函数(Extension Functions)

1. 基本用法

扩展函数允许为现有类添加新方法,无需继承或修改原始类。

示例代码:

kotlin
代码解读
复制代码
// 为String添加判断是否为有效邮件的扩展函数 fun String.isValidEmail(): Boolean { return matches(Regex("[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}")) } // 为Int添加计算阶乘的扩展函数 fun Int.factorial(): Long { return if (this <= 1) 1 else this * (this - 1).factorial() } fun main() { println("[email protected]".isValidEmail()) // 输出:true println(5.factorial()) // 输出:120 }

使用场景:

  • 为第三方库或系统类添加实用方法。
  • 增强代码可读性,如 list.quickSort()。

2. 扩展属性

类似扩展函数,可以为类添加“属性”(实际是计算属性,无幕后字段)。

示例代码:

kotin
代码解读
复制代码
val String.firstLetter: Char get() = if (isEmpty()) ' ' else this[0] fun main() { println("Kotlin".firstLetter) // 输出:K }

使用场景:

  • 提供基于现有属性的快捷访问方式,如 file.extension。

3. 扩展与成员冲突

当扩展函数与类成员函数同名时,成员函数优先。

示例代码:

kotlin
代码解读
复制代码
class Example { fun print() = println("成员函数") } fun Example.print() = println("扩展函数") fun main() { Example().print() // 输出:成员函数 }

三、注意事项

1. 委托的可见性:

  • 委托对象需在类构造时初始化。
  • 避免在委托中持有外部类的引用导致内存泄漏。

2. 扩展的限制:

  • 无法访问类的私有成员。
  • 扩展是静态解析的,不具备多态性。

3. 性能考量:

  • lazy 委托默认是线程安全的,若不需要同步可用 lazy(LazyThreadSafetyMode.NONE) 提升性能。

四、总结

特性适用场景优势
类委托组合优于继承、装饰器模式减少重复代码,提升灵活性
属性委托懒加载、属性监听、验证逻辑逻辑复用,代码简洁
扩展函数增强现有类功能、第三方库适配无侵入式扩展,提高可读性
扩展属性提供快捷访问属性简化复杂计算逻辑的调用

合理运用委托和扩展函数,能显著提升Kotlin代码的简洁性和可维护性,但需注意避免滥用导致结构混乱。

更多分享

  1. 一文吃透Kotlin中冷流(Clod Flow)和热流(Hot Flow)
  2. 一文带你吃透Kotlin协程的launch()和async()的区别
  3. 一文带你吃透接口(Interface)结合 @AutoService 与 ServiceLoader 详解
  4. Kotlin 作用域函数(let、run、with、apply、also)的使用指南
  5. 一文带你吃透Kotlin中 lateinit 和 by lazy 的区别和用法
注:本文转载自juejin.cn的QING618的文章"https://juejin.cn/post/7486322280861532214"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top