Kotlin 全面学习之路 (十一) -- 密封类

1、声明密封类

声明一个密封类需要在类名前添加 sealed 修饰符。

2、什么是密封类

密闭类用来表示 受限类继承 结构,什么意思?我们看一下官方的解释:当一个值为有限集中的类型(容易引起歧义-- 是有限 *集中* 还是 *有限集* 中,在此处我认为是 有限集 中,但是我却在这里跳了坑)、而不能有任何其他类型。什么是有限集中?说实话看到这样的定义我还是不能理解到底什么是 密封类。看一下原文吧

Sealed classes are used for representing restricted class hierarchies, when a value can have one of the types from a limited set, but cannot have any other type. They are, in a sense, an extension of enum classes: the set of values for an enum type is also restricted, but each enum constant exists only as a single instance, whereas a subclass of a sealed class can have multiple instances which can contain state.

自己翻译一下,如下

当一个值可以为有限集合中的一个类型但不能是其他的类型时,密封类用来表示这种受限的类层次结构。在某种意义上,密封类是枚举类的扩展,对于一个枚举类来说它的值也是有限制的,而且每个枚举类常量只存在一个实例,但是密封类的子类可以拥有包含状态的多个实例。

个人理解的是枚举类和密封类的不同为: 密封类的有限集合的元素为 类型,而枚举类的有限集合为 ,两者所面向的维度是不同的。或者也可以这么说:密封类适用于子类可数的情况,枚举适用于实例可数的情况。

从上文我们知道密封类可以有子类,但是这是有限制的:密封类的子类只能定义在密封类的内部或同一个文件中,因为其构造方法为私有的

sealed class Expr
data class Const(val number: Double) : Expr()
data class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()

另外,密封类还有一些其他需要注意的点:

  • 密封类自身是抽象的,无法直接实例化并可以有抽象成员
  • 密封类不可以有非 private 构造函数(默认为 private)
  • 扩展密封类子类的类可以放在任何处,不必非像其子类一样位于密封类的内部或者是在同一个文件中

3、密封类的使用

我们都知道在使用 when 表达式 作为表达式时 else 语句 不可缺少,而使用密封类的一个关键好处在 如果验证语句覆盖了所有情况,就不需要为该 when 表达式添加 else 语句

fun eval(expr: Expr): Double = when(expr) {
  is Const -> expr.number
  is Sum -> eval(expr.e1) + eval(expr.e2)
  NotANumber -> Double.NaN
  // 不再需要 `else` 子句,因为我们已经覆盖了所有的情况
}

参考资料

官方文档
Kotlin学习笔记(四十一)密封类

你可能感兴趣的:(Kotlin,全面学习之路)