Kotlin -- Sealed Classes
Kotlin – Sealed Classes
如果有一个接口类interface Expr
,其有两个实现:
interface Expr
class Num(val value: Int) : Expr class Sum(val left: Expr, val right: Expr) : Expr
当你用when
表达式处理的时候,必须有else
分支来作为默认选择:
fun eval(e: Expr): Int =
when (e) {
is Num -> e.value
is Sum -> eval(e.left) + eval(e.right)
else -> throw IllegalArgumentException("Unknown expression")
}
如果此时再实现一个interface Expr
的类class A
,编译器不会强制要求你在when
中新增分支来检测,如果你忘记增加新的分支来处理这个类,默认的else
分支将会被选择,那就有可能会在这里出现BUG。
避免这一问题的方法就是使用sealed class
:
sealed class Expr {
class Num(val value: Int) : Expr() class Sum(val left: Expr, val right: Expr) : Expr() } fun eval(e: Expr): Int = when (e) { is Expr.Num -> e.value is Expr.Sum -> eval(e.left) + eval(e.right) }
将超类标记为sealed
,其所有子类必须作为nested class
在超类中声明。此时当你使用when
时,就不需要使用else
分支了,因为此时所有的可能就是超类的所有子类,不会再出现其他情况。
sealed class
不能被定义在其外部的类继承,其构造函数是private
的,只能在内部被其子类调用。所以也无法声明一个sealed interface
。
目前来说,sealed
的功能受很大的限制,比如说其所有子类必须是nested
,也不能被作为一个data class
使用。