一文弄懂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 特色功能之一。

相关推荐
QING61836 分钟前
Jetpack Compose Brush API 简单使用实战 —— 新手指南
android·kotlin·android jetpack
QING6182 小时前
Jetpack Compose Brush API 详解 —— 新手指南
android·kotlin·android jetpack
鹿里噜哩2 小时前
Spring Authorization Server 打造认证中心(二)自定义数据库表
spring boot·后端·kotlin
用户69371750013848 小时前
23.Kotlin 继承:继承的细节:覆盖方法与属性
android·后端·kotlin
Haha_bj8 小时前
五、Kotlin——条件控制、循环控制
android·kotlin
Kapaseker9 小时前
不卖课,纯干货!Android分层你知多少?
android·kotlin
urkay-1 天前
Android 切换应用语言
android·java·kotlin·iphone·androidx
杀死那个蝈坦1 天前
监听 Canal
java·前端·eclipse·kotlin·bootstrap·html·lua
Yang-Never1 天前
Open GL ES->EGL渲染环境、数据、引擎、线程的创建
android·java·开发语言·kotlin·android studio
urkay-1 天前
Android 全局修改设备的语言设置
android·xml·java·kotlin·iphone