Подтвердить что ты не робот

Каковы различия между окончательным классом и закрытым классом в Scala?

В Scala есть два типа модификаторов: final и sealed

Каковы различия между ними? Когда вы должны использовать один над другим?

4b9b3361

Ответ 1

Класс final не может быть расширен, период.

A sealed признак может быть расширен только в том же исходном файле, который был объявлен. Это полезно для создания ADT (алгебраических типов данных). ADT определяется суммой его производных типов.

например:.

  • An Option[A] определяется Some[A] + None.
  • A List[A] определяется :: + Nil.

sealed trait Option[+A]

final case class Some[+A] extends Option[A]
object None extends Option[Nothing]

Поскольку Option[A] запечатан, он не может быть расширен другими разработчиками - это может изменить его значение.

Some[A] является окончательным, поскольку он не может быть расширен, период.


В качестве дополнительного бонуса, если черта запечатана, компилятор может предупредить вас, если совпадение с шаблоном недостаточно полно, потому что известно, что Option ограничено Some и None.

opt match {
    case Some(a) => "hello"
}

Предупреждение: совпадение не может быть исчерпывающим. Он потерпит неудачу при следующем вводе: None

Ответ 2

sealed классы (или признаки) все еще могут быть наследованы в том же исходном файле (где final классы не могут быть унаследованы вообще).

Используйте sealed, если вы хотите ограничить количество подклассов базового класса (см. "Алгебраический тип данных" ).

Как одно из самых практических преимуществ такого ограничения, компилятор теперь может предупредить вас о совпадениях, отличных от exaustive:

sealed trait Duo
case class One(i:Int) extends Duo
case class Two(i:Int, j:Int) extends Duo

def test(d:Duo) {
  match {
    case One(x) => println(x) // warning since you are not matching Two
  }
}