一、先一句话讲清楚:密封类是啥?
密封类 = 受限制的类 + 加强版枚举
- 它用来表示有限的、固定的、可枚举的类型
- 比如:网络请求结果、页面事件、状态、操作类型...
- 它的子类数量是固定的,不能随便加
核心作用:让类型更安全,when 表达式不用写 else!
二、超级通俗比喻
密封类就像手机的操作:
- 开机
- 关机
- 重启
- 调节音量
就这几种,不会突然冒出一个 “炒菜” 操作。密封类就是把固定类型全部列出来,不允许乱加。
三、基础语法(最标准写法)
1. 定义密封类
kotlin
// 关键字:sealed class
sealed class Result {
// 所有子类必须写在里面
object Success : Result() // 无参数
object Loading : Result() // 无参数
data class Error(val msg: String) : Result() // 带参数
}
定义一个叫 Result 的 “结果家族”,里面只有 3 个成员,任何时候都只能是这 3 种结果之一,不能多也不能少。
表格
| 成员 | 类型 | 作用 | 为啥这么写? |
|---|---|---|---|
| Success | object(单例) | 表示 “请求成功” | 成功只需要 1 个状态,不需要额外数据,用单例最省内存 |
| Loading | object(单例) | 表示 “加载中” | 加载中只是一个状态,不带数据,用 object 最合适 |
| Error | data class(数据类) | 表示 “请求失败” | 失败必须带错误信息(msg),用 data class 自动存数据 |
2. 使用(when 表达式,最爽!)
kotlin
fun handleResult(result: Result) {
when (result) {
is Result.Success -> println("成功")
is Result.Loading -> println("加载中")
is Result.Error -> println("错误:${result.msg}")
// 不用写 else!!!因为密封类子类是固定的
}
}
3. 总结(背会这 3 句)
- sealed class = 固定成员的 “家族” ,所有子类必须在同一文件定义
- object = 无数据状态(Loading/Success),data class = 带数据状态(Error)
- when 表达式不用 else,编译器强制覆盖所有情况,类型安全
四、密封类两种子类写法(必掌握)
1. 无参数 → 用 object(单例)
kotlin
sealed class HomeIntent {
object LoadData : HomeIntent()
object RefreshData : HomeIntent()
}
使用:
kotlin
HomeIntent.LoadData
2. 带参数 → 用 data class
kotlin
sealed class HomeIntent {
data class ItemClick(val position: Int) : HomeIntent()
}
使用:
kotlin
HomeIntent.ItemClick(5)
3. 完整用法:
1、在Activity中调用:
//1、调用
Utils.optionalFunction( HomeIntent.Success)
Utils.optionalFunction( HomeIntent.Loading)
Utils.optionalFunction( HomeIntent.ItemClick(5))
2、在Utils或ViewMOdel中使用:
object Utils {
/***
* 2、执行过程
*/
fun optionalFunction(homeIntent: HomeIntent) {
when (homeIntent) {
is HomeIntent.Success -> {
println("Operation successful")
}
is HomeIntent.Loading -> {
println("Loading...")
}
is HomeIntent.ItemClick -> {
println("Item clicked at position: ${homeIntent.position}")
}
}
}
}
/***
* 3、密封类
*/
sealed class HomeIntent {
object Success : HomeIntent() // 无参数
object Loading : HomeIntent() // 无参数
data class ItemClick(val position: Int) : HomeIntent()// 带参数
}
五、密封类最常用的 3 大场景(实战)
场景 1:网络请求状态(最常用)
kotlin
sealed class NetResult<out T> {
object Loading : NetResult<Nothing>()
data class Success<T>(val data: T) : NetResult<T>()
data class Error(val msg: String) : NetResult<Nothing>()
}
使用:
kotlin
when(netResult) {
NetResult.Loading -> 显示加载
is NetResult.Success -> 显示数据
is NetResult.Error -> 显示错误
}
场景 2:MVI 架构页面事件(你刚才的代码)
kotlin
sealed class HomeIntent {
object LoadData : HomeIntent()
object RefreshData : HomeIntent()
data class ItemClick(val pos: Int) : HomeIntent()
}
场景 3:页面状态 / 类型
kotlin
sealed class PageState {
object Empty : PageState()
object Content : PageState()
object Error : PageState()
}
六、密封类 VS 枚举类(超级清晰)
表格
| 特性 | 枚举 Enum | 密封类 Sealed Class |
|---|---|---|
| 类型 | 只能是常量 | 可以是类、带参数 |
| 传参 | 不能带复杂参数 | 可以带任意参数 |
| 扩展性 | 弱 | 强 |
| 适用 | 简单类型(性别、状态) | 复杂类型、事件、结果 |
一句话:枚举是简单常量,密封类是带结构、带数据的类型。
七、密封类的 4 个核心特性(面试必背)
- 子类数量固定所有子类必须定义在密封类内部
- 构造方法私有不能随便实例化
- when 表达式不用 else编译器知道所有子类
- 支持带参数 + 无参数灵活度极高
八、最简单总结(背会这 4 句)
- sealed class 是密封类,用来表示固定类型
- 子类用 object(无参)或 data class(有参)
- when 表达式不用 else,类型安全
- 主要用于:网络结果、MVI 事件、页面状态