一文弄懂Kotlin中的by关键字

在 Kotlin 中,by 关键字用于实现委托模式(Delegation)​ ,它允许将某些操作或责任委托给另一个对象来处理。by 主要有两种用途:​类委托属性委托


1. 类委托(Class Delegation)

通过 by 关键字,可以将类的接口实现委托给另一个对象。这样可以在不继承的情况下复用现有类的功能。

示例:

kotlin 复制代码
interface Animal {
    fun makeSound()
}

class Dog : Animal {
    override fun makeSound() {
        println("Woof!")
    }
}

// 通过 by 将 Animal 接口的实现委托给 dog 对象
class Robot(private val dog: Dog) : Animal by dog {
    fun move() {
        println("Robot is moving")
    }
}

fun main() {
    val dog = Dog()
    val robot = Robot(dog)
    robot.makeSound() // 实际调用的是 Dog 的 makeSound()
    robot.move()      // Robot 的独有方法
}
  • 作用Robot 类通过 by dog 委托了 Animal 接口的实现,无需手动重写 makeSound()
  • 优势:避免重复代码,优先组合而非继承。

2. 属性委托(Property Delegation)

通过 by 将属性的 getter/setter 逻辑委托给一个委托对象 ​(需实现 getValue()setValue() 方法)。Kotlin 标准库提供了几种常用委托:

常见用途:

(1)懒加载委托 lazy

属性在首次访问时初始化。

kotlin 复制代码
val heavyData: String by lazy {
    println("Computing heavy data...")
    "Heavy Result"
}

fun main() {
    println(heavyData) // 第一次访问时计算并缓存
    println(heavyData) // 直接返回缓存结果
}
(2)观察者委托 Delegates.observable

属性变化时触发回调。

kotlin 复制代码
import kotlin.properties.Delegates

var name: String by Delegates.observable("Alice") { _, old, new ->
    println("Name changed: $old -> $new")
}

fun main() {
    name = "Bob" // 输出: Name changed: Alice -> Bob
}
(3)非空校验委托 Delegates.notNull

延迟初始化但确保非空。

kotlin 复制代码
var age: Int by Delegates.notNull<Int>()

fun main() {
    age = 30
    println(age) // 必须先赋值,否则抛 IllegalStateException
}
(4)自定义委托

实现 ReadWritePropertyReadOnlyProperty 接口。

kotlin 复制代码
class StringDelegate(private var value: String) {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        println("Getting value: $value")
        return value
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: String) {
        println("Setting value: $newValue")
        value = newValue
    }
}

var text by StringDelegate("Default")

fun main() {
    println(text) // 输出: Getting value: Default
    text = "New"  // 输出: Setting value: New
}

关键点总结:

  • 类委托 :通过 by 将接口实现委托给其他对象。
  • 属性委托 :将属性的访问逻辑委托给 lazyobservable 或自定义对象。
  • 优势:减少重复代码,实现关注点分离(如懒加载、观察模式等)。

通过 by,Kotlin 以简洁的语法实现了强大的委托模式,是 Kotlin 特色功能之一。

相关推荐
alexhilton37 分钟前
Jetpack Compose的性能优化建议
android·kotlin·android jetpack
天枢破军3 小时前
【KMP】桌面端打包指南
kotlin
_一条咸鱼_4 小时前
深度解析 Android MVI 架构原理
android·面试·kotlin
好学人4 小时前
Android MVVM 架构中的重要概念
kotlin·mvvm
好学人4 小时前
一文弄懂 repeatOnLifecycle
kotlin·mvvm
天枢破军4 小时前
【KMP】解决桌面端打包异常无法运行
kotlin
zhangphil5 小时前
Android ExifInterface rotationDegrees图旋转角度,Kotlin
android·kotlin
好学人11 小时前
Kotlin中的作用域关键字
kotlin
QING61815 小时前
详解:Kotlin 类的继承与方法重载
android·kotlin·app