2013-08-08 2 views
1

Рассмотрим два класса А и В:Почему мы можем создавать новые классы, полученные из запечатанных (scala) в java?

// 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), или мне нужно написать фиктивный последний случай в каждом матче шаблона для обеспечения безопасности коды?

ответ

4

Возможно создать их из Java в качестве детали, которую заклеил класс Scala, только сам компилятор Scala. Компилятор Java не имеет понятия, что A.Nat полностью закрыт.

Также как примечание стороны, вы должны отметить Succ как запечатанный, так как иначе даже в Scala кто-то может его расширить.