介绍
当对象具有来自有限集的类型之一(密封类对子类有限制),但不能具有任何其他类型时,使用密封类。(例如网络请求数据只能是请求成功、请求失败)
class Expr
class Const(val value: Int) : Expr
class Sum(val left: Expr, val right: Expr) : Expr
fun eval(e: Expr): Int =
when (e) {
is Const -> e.value
is Sum -> eval(e.right) + eval(e.left)
else ->
throw IllegalArgumentException("Unknown expression")
}
如果添加一个新的类(NotANumber)上边会走else。下边Sealed会在编译时提示你。
sealed class Expr
class Const(val value: Int) : Expr()
class Sum(val left: Expr, val right: Expr) : Expr()
object NotANumber : Expr()
fun eval(e: Expr): Int =
when (e) {
is Const -> e.value
is Sum -> eval(e.right) + eval(e.left)
NotANumber -> java.lang.Double.NaN
}
使用Demo
网络请求 数据回调covert
/**
* 密封类
* 转换接口请求的数据
* success 数据正常返回
* error 数据异常情况
*/
sealed class ApiResult<out T:Any> {
data class Success<out T:Any>(val data:T):ApiResult<T>()
data class Error(var errorCode:ErrorCode,var errorMsg:String):ApiResult<Nothing>()
}
enum class ErrorCode{
NETERROR,
ERROR,
NOTLOGIN
}
class Repository {
fun login(phone:String,pwd:String):ApiResult<String>{
//请求接口 api.login()
//转换接口请求数据
return if (phone.isNotEmpty()){
ApiResult.Success("success")
}else{
ApiResult.Error(ErrorCode.ERROR,"找不到www.xxx.com")
}
}
}
class LoginModule {
val repo by lazy { Repository() }
fun login(){
val result = repo.login("1232131231", "123")
when(result){
is ApiResult.Success ->{
println(result.data)
}
is ApiResult.Error ->{
when(result.errorCode){
ErrorCode.ERROR ->{}
ErrorCode.NOTLOGIN ->{}
}
}
}
}
}
注意事项
- 所有子类必须在密封类同一文件声明
- 密封类是抽象的不能实例化
- 不能创建非私有构造函数,因为默认是private的