You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中如何对共享相同变量的自定义对象执行相同操作?

Kotlin sealed class多子类公共属性处理方案

你遇到的是Kotlin智能转型的限制:多类型联合匹配的分支不会自动提取不同类型的同名公共属性,以下是几种可落地的优化方案:

方案1:抽取公共接口(最推荐,结构最合理)

先定义包含公共属性的接口,让带直接timestamp的子类实现该接口:

interface TimestampHolder {
    var timestamp: String?
}

sealed class Example {
    // 注:原示例类名不符合Kotlin命名规范,统一调整为首字母大写
    data class Foo1(override var timestamp: String?, var model1: Model1?): Example(), TimestampHolder
    data class Foo2(override var timestamp: String?, var model2: Model2?): Example(), TimestampHolder
    data class Foo3(var model3: Model3?): Example()
}

调整后业务代码可以直接简化为:

when(foo) {
    is TimestampHolder -> foo.timestamp = ts
    is Foo3 -> foo.model3.timestamp = ts
}

后续新增同类型带timestamp的子类只要实现TimestampHolder接口即可,无需修改现有业务分支,可扩展性最强。

方案2:扩展属性兼容现有结构

如果不想改动原有sealed class的定义,可以通过扩展属性统一封装timestamp的读写逻辑:

var Example.timestamp: String?
    get() = when(this) {
        is Example.Foo1 -> timestamp
        is Example.Foo2 -> timestamp
        is Example.Foo3 -> model3?.timestamp
    }
    set(value) {
        when(this) {
            is Example.Foo1 -> timestamp = value
            is Example.Foo2 -> timestamp = value
            is Example.Foo3 -> model3?.timestamp = value
        }
    }

封装后业务逻辑可以直接一行实现,完全不需要分支判断:

foo.timestamp = ts

如果后续不同类型的赋值逻辑有调整,只需要修改扩展属性的setter即可,上层调用无需改动。

方案3:无结构改动的临时写法

如果只是临时需求不想调整现有结构,也可以在联合分支中手动强转实现:

when(foo) {
    is Example.Foo1, is Example.Foo2 -> {
        (foo as TimestampHolder).timestamp = ts
    }
    is Example.Foo3 -> foo.model3.timestamp = ts
}

该方案不建议长期使用,后续新增子类时仍需要修改分支,维护成本较高。


内容的提问来源于stack exchange,提问作者misfit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 19:48:03