跳转到正文
YGJoon 技术博客

Android Kotlin 面向对象与委托模式

发布于:
·983 字 · 约 2 分钟·作者:
Kotlin 面向对象精髓:数据类、密封类状态建模,by 关键字做类委托与属性委托,组件化中的真实用例。
Android Kotlin 面向对象与委托模式文章封面
目录

类与构造函数

class UserService(private val api: ApiService) {
    fun load(id: Long): User = api.getUser(id)
}

class UserRepository @Inject constructor(
    private val local: UserLocalDataSource,
    private val remote: UserRemoteDataSource
) {
    fun getUser(id: Long): Flow<User> {
        return remote.fetchUser(id)
            .onEach { local.save(it) }
            .catch { emitAll(local.observe(id)) }
    }
}

次构造函数

class ErrorResponse(val code: Int, val message: String) {
    constructor(exception: Throwable) : this(500, exception.message ?: "Unknown")
}

数据类与复制

data class UiState(
    val loading: Boolean = false,
    val data: List<Article> = emptyList(),
    val error: Throwable? = null
)

val newState = oldState.copy(loading = true)

密封类与枚举

sealed interface LoginResult {
    data class Success(val user: User) : LoginResult
    data class Failure(val error: Throwable) : LoginResult
    data object Loading : LoginResult
}

fun render(result: LoginResult) = when (result) {
    is LoginResult.Success -> showUser(result.user)
    is LoginResult.Failure -> showError(result.error)
    LoginResult.Loading -> showLoading()
}

接口与委托

1. 接口实现

interface Analytics {
    fun track(event: String)
}

class FirebaseAnalytics : Analytics {
    override fun track(event: String) {
        Log.d("analytics", "track=$event")
    }
}

2. 类委托

class AnalyticsLogger(private val analytics: Analytics) : Analytics by analytics {
    override fun track(event: String) {
        Log.d("analytics", "event=$event")
        analytics.track(event)
    }
}

val analytics: Analytics = AnalyticsLogger(FirebaseAnalytics())

3. 属性委托

class PreferenceDelegate<T>(
    private val prefs: SharedPreferences,
    private val key: String,
    private val default: T
) {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
        return when (default) {
            is String -> prefs.getString(key, default) as T
            is Int -> prefs.getInt(key, default) as T
            else -> default
        }
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
        prefs.edit().apply {
            when (value) {
                is String -> putString(key, value)
                is Int -> putInt(key, value)
            }
        }.apply()
    }
}

class UserPreferences(prefs: SharedPreferences) {
    var token: String by PreferenceDelegate(prefs, "token", "")
}

组件化中的委托案例

1. Activity 结果回调

class PhotoPickerHandler(activity: ComponentActivity) {
    private val launcher = activity.registerForActivityResult(
        ActivityResultContracts.PickVisualMedia()
    ) { uri ->
        uri?.let(onPhotoPicked)
    }

    var onPhotoPicked: (Uri) -> Unit = {}

    fun selectPhoto() {
        launcher.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
    }
}

2. Compose 状态持有

class UiStateHolder(initial: UiState) {
    var state by mutableStateOf(initial)
        private set

    fun update(block: UiState.() -> UiState) {
        state = block(state)
    }
}

设计建议

实战案例:by lazy 是 Kotlin 给得最好的”语法糖”

Kotlin 的委托(delegation)分两种,实战价值天差地别:

  1. 类委托 by:class MySet<T>(private val inner: MutableSet<T>) : MutableSet<T> by inner,一行实现装饰器模式。Dart 里没有语言级委托,得手写转发方法(或者 code gen)。但说实话,实战里类委托用得很少——组合优于继承,现代代码里直接”包一层”更直观。
  2. 属性委托 by lazy / by Delegates.observable():这个是真香。val config by lazy { loadConfig() }——第一次访问才初始化,线程安全,Dart 里要自己写 Config? _cache; Config get config => _cache ??= loadConfig(); 三行。Delegates.observable 更绝:var name by Delegates.observable("") { _, old, new -> println("$old -> $new") },属性监听一行搞定,Dart 得上 ValueNotifier + addListener。

我在 Flutter 里最怀念的就是 by lazy——Dart 的 late 是”延迟到第一次用”,但不缓存判空逻辑,还容易 LateInitializationError。Kotlin 这套属性委托,是把”样板代码”上升成了”语言特性”。

参考:Kotlin 官方文档《Delegation》;《Delegated properties》

总结

  1. Kotlin 的面向对象特性与 Java 兼容,同时提供数据类、密封类等增强特性。
  2. 委托模式可减少样板代码,广泛适用于属性持有、能力增强、状态封装等场景。
  3. 合理结合 OOP 与函数式能力,是构建可维护 Android 架构的关键。

下一篇将进入集合操作与标准库,探索 Kotlin 如何提升数据处理效率。


分享这篇文章



相关文章

上一篇
Android Kotlin 函数式编程与控制流
下一篇
Android Kotlin 集合操作与标准库实战
YGJoon 的头像

YGJoon

记录 Flutter、Web 与原生移动端工程实践。更多背景见关于页,源码与项目见GitHub。