Scala';s密封抽象vs抽象类

Scala';s密封抽象vs抽象类,scala,class,abstract,sealed,Scala,Class,Abstract,Sealed,sealed abstract和abstractScala类之间有什么区别?区别在于,一个密封类的所有子类(无论是否抽象)都必须与密封类位于同一个文件中。因为,一个密封类的所有直接继承子类(抽象或非抽象)都必须位于同一个文件中。这样做的一个实际结果是,如果模式匹配不完整,编译器可以发出警告。例如: sealed abstract class Tree case class Node(left: Tree, right: Tree) extends Tree case class Leaf[T](

sealed abstract
abstract
Scala类之间有什么区别?

区别在于,一个密封类的所有子类(无论是否抽象)都必须与密封类位于同一个文件中。

因为,一个密封类的所有直接继承子类(抽象或非抽象)都必须位于同一个文件中。这样做的一个实际结果是,如果模式匹配不完整,编译器可以发出警告。例如:

sealed abstract class Tree
case class Node(left: Tree, right: Tree) extends Tree
case class Leaf[T](value: T) extends Tree
case object Empty extends Tree

def dps(t: Tree): Unit = t match {
  case Node(left, right) => dps(left); dps(right)
  case Leaf(x) => println("Leaf "+x)
  // case Empty => println("Empty") // Compiler warns here
}

如果
密封的
,那么编译器会发出警告,除非最后一行没有注释。

不太明显的一点(至少对我来说不是:-)是密封类的“孙子辈”也可以在其他文件中:给定密封类A;B延长A;C扩展B.B必须与A在同一个文件中,但C可以保留在同一个文件中或另一个文件中。@SandorMurakozi如果要实现这一点,您还必须将B声明为密封类。密封只处理直接继承。如果没有
sealed
关键字,为什么编译器不能推断模式匹配是不完整的?@sasha.sochka假设我编译它并将其放入jar文件中,而没有
sealed
关键字。所有这些都是在那时编译的,包括
match
语句。现在,另一个用户抓住这个jar并扩展
。没有什么可以阻止他这么做,但是,此时,
match
语句不再完整。因为他不是在编译它,只是从您的jar中使用它,所以编译器不能警告他。由于您在创建jar时不知道它,所以它不可能警告您。@DanielCSobral,您写道“但是,此时,匹配语句不再完整”。在创建jar文件之前,当您编译发布的原始代码(但没有
sealed
关键字)时,match语句不是不完整吗?这看起来很容易推断,因为即使没有新的子项(编译器还不知道它们),也没有
Empty
的分支。我说的是对创建jar的人的警告,而不是对使用jar的人的警告。@sasha.sochka好吧,我想它可能会警告缺少
Empty
,但问题是,即使你添加
Empty
,它也可能不完整,或者不完整,这取决于单独编译时发生的情况。是的,那我同意你的看法。