阅读 150

Kotlin 密封类(Sealed)

在本文中,您将在示例的帮助下了解Sealed (密封)类,如何创建它们以及何时使用它们。

当值只能从有限的集合(受限的层次结构)中包含一个类型时,将使用密封类。

在详细介绍密封类之前,让我们探讨它们解决的问题。让我们举个实例:

示例

class Exprclass Const(val value: Int) : Exprclass Sum(val left: Expr, val right: Expr) : Exprfun 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表达式中的默认条件。

现在,如果您从Expr类派生一个新的子类,则编译器将不会检测到任何东西,因为 else 分支会对其进行处理,这可能会导致错误。 如果在添加新的子类时编译器发出错误,那就更好了。

要解决此问题,可以使用密封类。 如前所述,密封类限制了创建子类的可能性。 而且,当您在when表达式中处理密封类的所有子类时,不必使用else分支。

要创建密封类,请使用密封修饰符 sealed 。例如,

sealed class Expr

示例:密封类使用示例

这是使用密封类解决上述问题的方法:

示例

sealed class Exprclass 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 表达式中处理的,否则编译器将报告。

几个重要注意事项

  • 密封类的所有子类必须在声明密封类的同一文件中声明。

  • 密封类本身是抽象的,您不能从中实例化对象。

  • 不能创建密封类的非私有构造函数;默认情况下,它们的构造函数是 private。

枚举和密封类之间的区别

枚举类和密封类非常相似。枚举类型的值集也像密封类一样受到限制。

唯一的区别是,枚举只能有一个实例,而密封类的子类可以有多个实例。


文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐