В чем разница между sealed abstract
и abstract
Scala class?Запечатанный ансамбль Scala vs abstract class
ответ
Разница заключается в том, что все подклассы закрытого класса (будь то абстрактные или нет) должны быть в том же файле, что и закрытый класс.
Как answered, все непосредственно наследующий подклассы закрытого класса (абстрактные или нет) должны быть в одном файле. Практическим следствием этого является то, что компилятор может предупредить, если совпадение шаблона является неполным. Например:
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
}
Если Tree
является sealed
, то компилятор предупреждает, если что последняя строка не является раскомментировать.
Почему компилятор не может сделать вывод о том, что совпадение шаблона является неполным, если нет ключевого слова «запечатанное»? –
@ sasha.sochka Предположим, что я скомпилировал его и поместил в файл jar без ключевого слова «запечатанное». В этот момент все было скомпилировано, включая инструкцию 'match'. Теперь другой пользователь захватывает эту банку и расширяет «Дерево». Ничто не мешает ему это сделать, но в этот момент утверждение 'match' больше не завершено. Поскольку он не компилирует его, просто используя его из вашей банки, компилятор не может предупредить _him_. И так как вы не знали об этом, когда создали банку, это не могло вас предупредить. –
@DanielCSobral, Вы написали «но, в точке *, *, утверждение соответствия больше не завершено». Не является ли совпадением утверждение в момент * этого * момента, когда вы компилируете исходный код, который вы опубликовали (но без ключевого слова «запечатанное»), перед тем, как сделать файл jar? Это выглядит легко, потому что даже без новых детей (компилятор еще не знает о них) нет ветки для 'Empty'. И я говорю о предупреждении для человека, который создает банку, а не о человеке, который его использует. –
Что-то не так очевидно (по крайней мере, это было не для меня :-)), так это то, что «великие дети» запечатанного класса могут быть и в других файлах: Учитывая герметичный класс A; B расширяет A; C расширяет B. B должен находиться в том же файле, что и A, но C может оставить его в том же или другом. –
@SandorMurakozi Вы должны объявить B как запечатанный класс, если хотите этого. Уплотнение касается только прямого наследования. – natbusa