多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# Kotlin 密封类 > 原文: [https://www.programiz.com/kotlin-programming/sealed-class](https://www.programiz.com/kotlin-programming/sealed-class) #### 在本文中,您将在示例的帮助下了解密封类,如何创建它们以及何时使用它们。 当值只能具有有限集合(受限制的层次结构)中的一种类型时,使用密封类。 * * * 在详细介绍密封类之前,让我们探讨它们解决的问题。 让我们举个例子(摘自 Kotlin 官方网站-[密封类](https://kotlinlang.org/docs/reference/sealed-classes.html)文章): ```kt 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") } ``` 在上述程序中,基类`Expr`具有两个派生类`Const`(代表一个数字)和`sum`(代表两个表达式的总和)。 在这里,必须使用`else`分支作为`when`表达式的[默认条件](/kotlin-programming/when-expression "Kotlin when expression")。 现在,如果您从`Expr`类派生新的子类,则编译器将不会检测到任何东西,因为`else`分支对其进行处理会导致错误。 如果在添加新的子类时编译器发出错误,那就更好了。 要解决此问题,可以使用密封类。 如前所述,密封类限制了创建子类​​的可能性。 并且,当您在`when`表达式中处理密封类的所有子类时,不必使用`else`分支。 * * * 要创建密封类,请使用密封修饰符。 例如, ```kt sealed class Expr ``` * * * ### 示例:密封类 使用密封类可以解决上述问题: ```kt 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 } ``` 如您所见,没有`else`分支。 如果您从`Expr`类派生新的子类,则除非该子类在`when`表达式中进行处理,否则编译器将抱怨。 * * * ### 几个重要说明 * 密封类的所有子类必须在声明了密封类的同一文件中声明。 * 密封类本身就是[抽象](https://www.programiz.com/kotlin-programming/abstract-class "Kotlin Abstract class"),您不能从中实例化对象。 * 您不能创建密封类的非私有构造器。 它们的构造器默认为`private`。 * * * ### 枚举与密封类之间的区别 *枚举类*和密封类非常相似。 枚举类型的值集也像密封类一样受到限制。 唯一的区别是,枚举只能有一个实例,而密封类的子类可以有多个实例。