Kotlin面向对象之封闭类(Sealed Classes)

封闭类用于反应被限制了的类层次结构:一个值的类型只能是有限集合中的一种,而不能是集合外的其他类型。它们在某种意义上是枚举类的扩展:枚举类型的值的集合也被限制,每个枚举常量仅作为单个实例存在;然而封闭类的子类可以有多个实例,且这些实例仍然可以持有状态。

要想声明一个封闭类,需要在类名前添加sealed修饰符。一个封闭类可以有子类,但是这些子类必须在和封闭类同一个文件中声明。(在Kotlin1.1之前,规则更苛刻:子类必须嵌套在封闭类的内部)。

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

fun eval(expr: Expr): Double = when (expr) {
    is Const -> expr.number
    is Sum -> eval(expr.e1) + eval(expr.e2)
    NotANumber -> Double.NaN
}

(上面这段代码使用了Kotlin1.1的一个新特性:数据类可以继承其他类,也包括封闭类。)

注意:继承(直接继承)封闭类的子类的类,可以放置在其他任意地方,不必非要放在同一个文件中。

使用密封类的关键好处是在使用when表达式时使用它们。如果可以保证该语句涵盖了所有情况,则不需要在语句中添加一个else子句。

fun eval(expr: Expr): Double = when(expr) {
    is Expr.Const -> expr.number
    is Expr.Sum -> eval(expr.e1) + eval(expr.e2)
    Expr.NotANumber -> Double.NaN
    // the `else` clause is not required because we've covered all the cases
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young阅读 3,890评论 1 10
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,767评论 18 399
  • 常量与变量使用let来声明常量,使用var来声明变量。声明的同时赋值的话,编译器会自动推断类型。值永远不会被隐式转...
    莫_名阅读 466评论 0 1
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,973评论 19 139
  • 你說我經常給你添麻煩,麻煩死了,於是我學著再也不找你,能自己幹就幹,不能就算了。 你說我哭的時候比笑的時候更好看,...
    小海妖MIKA阅读 169评论 0 0