考虑两个类 A 和 B:
// A.scala
object A {
sealed abstract class Nat
case object Zero extends Nat
case class Succ(n : Nat) extends Nat
def pp(n : Nat) = n match {
case Zero => println("Zero")
case Succ(m) => println("Succ")
case _ => println("WTF")
}
def main(args : Array[String]) =
pp(B.f())
}
// B.java
public class B {
static A.Nat f() {
return new A.Nat() {};
}
}
编译、运行:
$ scala A
WTF
如 documentation 中所述, "密封类不能被直接继承,除非继承模板定义在与被继承类相同的源文件中。"
我认为这意味着通过同一文件中定义的子类进行模式匹配就足以涵盖所有情况,但正如我们从这个例子中看到的那样,这是不正确的。
这里有一个问题:有没有办法编写真正密封类(如ADTs)或者我需要在每个模式匹配中编写虚拟的最后一个案例以确保代码安全?
最佳答案
可以从 Java 创建它们,因为 Scala 类的密封细节仅由 Scala 编译器本身提供。 Java 编译器根本不知道 A.Nat 是密封的。
另请注意,您需要将 Succ 标记为密封的,否则即使在 Scala 中也有人可以扩展它。
关于java - 为什么我们可以在 java 中创建从 sealed(scala) 派生的新类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18130801/