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

如何让Kotlin密封类方法返回子类实例而非父类类型?

解决Kotlin密封类父类方法返回子类类型的问题

要让密封类的父类方法返回当前子类的类型,无需强制转换,有两种常用实现方式:

方式一:泛型父类+子类重写(类型安全最优)

通过给父类定义递归泛型约束,让子类继承时指定自身为泛型参数,再重写方法返回自身类型。这种方式编译时就能保证类型正确性,没有强转风险。

sealed class Base<T : Base<T>> {
    abstract fun customCopy(): T
}

data class X(val x: String) : Base<X>() {
    override fun customCopy(): X = copy()
}

data class Y(val y: String) : Base<Y>() {
    override fun customCopy(): Y = copy()
}

fun main() {
    val x1 = X("x")
    val x2: X = x1.customCopy() // 直接编译通过,无需强转
}

方式二:父类集中逻辑+泛型推断(无需子类重写)

如果希望customCopy的逻辑统一留在父类,不用每个子类重写,可以借助泛型推断和安全强转实现。因为密封类的分支覆盖了所有可能的子类,强转是安全的。

sealed class Base {
    @Suppress("UNCHECKED_CAST")
    fun <T : Base> customCopy(): T = when (this) {
        is X -> copy() as T
        is Y -> copy() as T
    }
}

data class X(val x: String) : Base()
data class Y(val y: String) : Base()

fun main() {
    val x1 = X("x")
    val x2: X = x1.customCopy() // 编译器自动推断T为X,正常赋值
}

两种方式对比

  • 方式一:类型安全最高,编译期就能校验返回类型,但需要每个子类重写方法。
  • 方式二:逻辑集中在父类,子类无需额外代码,但依赖泛型推断,若手动指定错误类型会运行时出错(正常使用下编译器会自动推断正确类型)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 14:15:26