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

Kotlin中sealed class与sealed interface的区别及适用场景

Kotlin sealed interface 对比 sealed class 的优势与最佳实践

核心基础差异

两者都继承了sealed类型的核心特性:子类实现只能在同一个包下定义,when分支判断时可以自动做穷尽校验,不需要写else分支。除此以外,两者的差异完全对应普通类和接口的差异:

  • sealed class 是类类型,有构造函数,可以存储公共状态、实现公共/私有方法,子类只能继承一个sealed父类,受Java单继承规则限制
  • sealed interface 是接口类型,无构造函数,不能存储状态,默认所有方法都是公开抽象的,同一个类可以实现多个sealed interface

sealed interface 的独有优势

  • 支持多实现:同一个业务类型可以同时归入多个密封体系,比如你定义sealed interface Loadable 用来标记可加载状态、sealed interface Refreshable 用来标记可刷新状态,某个UI状态类可以同时实现这两个接口,在不同的业务判断场景下都能享受sealed类型的穷尽校验能力
  • 支持枚举类实现:这是sealed class做不到的特性,你可以把固定枚举值和其他自定义类型共同归入同一个密封体系,示例如下:
sealed interface NavRoute {
    object Home : NavRoute
    // 枚举类实现sealed interface
    enum class SecondaryRoute : NavRoute {
        USER_CENTER, SETTING, MESSAGE_CENTER
    }
    data class Detail(val id: Long) : NavRoute
}
  • 类型建模更轻量:不需要强制继承类的额外特性,纯类型分类的场景下代码冗余度更低

选型判断与最佳实践

不需要所有简单场景都强制优先用sealed interface,根据实际需求判断即可:

优先选sealed interface的场景

  • 密封体系下的子类不需要共享公共状态、不需要父类实现私有/非抽象公共方法
  • 需要多实现、需要枚举类归入当前密封体系
  • 用来定义事件、路由、操作符这类纯标记型的类型分类

必须选sealed class的场景

  • 所有子类需要共享父类的公共状态、或者需要父类实现公共的复用方法/私有方法
  • 需要限制子类的构造逻辑,比如通过父类私有构造函数统一管控子类的实例化规则

举个直观示例:如果你的网络请求状态需要统一存储请求ID用于链路追踪,用sealed class更合适:

sealed class NetworkState(val requestId: String) {
    class Loading(requestId: String) : NetworkState(requestId)
    class Success(requestId: String, val data: Any) : NetworkState(requestId)
    class Error(requestId: String, val throwable: Throwable) : NetworkState(requestId)
}

如果不需要统一存储公共状态,用sealed interface更灵活:

sealed interface NetworkState {
    object Loading : NetworkState
    data class Success(val data: Any) : NetworkState
    data class Error(val throwable: Throwable) : NetworkState
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 23:06:03