将案例类密封起来是一种好习惯吗?

Emi*_*erg 7 scala

密封类的主要原因似乎是,这允许编译器在对这些类进行模式匹配时进行彻底搜索.假设我有用于模式匹配的数据类型.玩具示例:

sealed trait Statement
case class Assign(name: String, value: Int) extends Statement
case class Print(name: String) extends Statement
case class IfZero(name: String, thenn: Statement, els: Option[Statement]) extends Statement
case class Block(statements: List[Statement]) extends Statement
Run Code Online (Sandbox Code Playgroud)

这些类的用例是通过模式匹配来使用它们:

def execute(statement: Statement): Unit = statement match {
    case Assign(name, value)      => ???
    case Print(name)              => ???
    case IfZero(name, thenn, els) => ???
    case Block(statements)        => statements foreach { execute(_) }
  }
Run Code Online (Sandbox Code Playgroud)

为此,Statement特性是sealed这样的,如果我在match语句中忘记了一个语句类型,编译器可以发出警告.但案例类怎么样?案例类不能相互继承,但特征和普通类可以.那么,密封案例类也是一种好的做法吗?如果我不这样做可能会出错?

kir*_*uku 9

您不必密封案例类,但您应将其标记为final,因此禁止任何进一步的继承关系.将它们密封只有在您想要对其子类进行穷举检查时才有用,这不是一个非常可能的用例.

将所有类标记为final默认值是一件好事,因为它禁止API的用户在覆盖其方法时更改这些类的行为.如果你没有专门设计你的类被子类化,那么子类化可能会导致应用程序中出现错误,因为子类化的类不再按照预期的方式执行.

  • “将它们密封起来仅在您需要对其子类进行详尽检查时才有用,而这不是一个很可能的用例。”这就是我一直在寻找的东西,也是我经过一番思考后得出的结论。如果处理了所有继承的案例类,则仍可以保证(密封的)基本特征的穷举性,因为根据定义,这些案例类的任何子类的任何实例也是这些案例类之一的实例。 (2认同)