Запечатанные классы Котлина

В этой статье вы узнаете о классах Sealed, о том, как они создаются и когда их использовать, с помощью примеров.

Запечатанные классы используются, когда значение может иметь только один из типов из ограниченного набора (ограниченные иерархии).

Прежде чем вдаваться в подробности о запечатанных классах, давайте разберемся, какую проблему они решают. Возьмем пример (взят с официального сайта Kotlin - статья Sealed classes):

 class Expr class Const(val value: Int) : Expr class Sum(val left: Expr, val right: Expr) : Expr fun eval(e: Expr): Int = when (e) ( is Const -> e.value is Sum -> eval(e.right) + eval(e.left) else -> throw IllegalArgumentException("Unknown expression") )

В приведенной выше программе базовый класс Expr имеет два производных класса: Const (представляет собой число) и Sum (представляет собой сумму двух выражений). Здесь обязательно использовать elseветку для условия по умолчанию в выражении when.

Теперь, если вы получите новый подкласс из Exprкласса, компилятор ничего не обнаружит, поскольку elseветвь обрабатывает его, что может привести к ошибкам. Было бы лучше, если бы компилятор выдавал ошибку при добавлении нового подкласса.

Чтобы решить эту проблему, вы можете использовать запечатанный класс. Как уже упоминалось, запечатанный класс ограничивает возможность создания подклассов. И, когда вы обрабатываете все подклассы запечатанного класса в whenвыражении, нет необходимости использовать elseветвь.

Для создания класса sealed используется модификатор sealed. Например,

 запечатанный класс Expr

Пример: запечатанный класс

Вот как можно решить указанную выше проблему с помощью запечатанного класса:

 sealed class Expr class Const(val value: Int) : Expr() class Sum(val left: Expr, val right: Expr) : Expr() object NotANumber : Expr() fun eval(e: Expr): Int = when (e) ( is Const -> e.value is Sum -> eval(e.right) + eval(e.left) NotANumber -> java.lang.Double.NaN ) 

Как видите, elseветки нет . Если вы получите новый подкласс от Exprкласса, компилятор будет жаловаться, если подкласс не обрабатывается в whenвыражении.

Несколько важных замечаний

  • Все подклассы запечатанного класса должны быть объявлены в том же файле, где объявлен запечатанный класс.
  • Запечатанный класс является абстрактным сам по себе, и вы не можете создавать из него объекты.
  • Вы не можете создавать неприватные конструкторы закрытого класса; их конструкторы privateпо умолчанию.

Разница между Enum и Sealed Class

Класс Enum и класс sealed очень похожи. Набор значений для типа перечисления также ограничен, как и для закрытого класса.

Единственное отличие состоит в том, что enum может иметь только один экземпляр, тогда как подкласс запечатанного класса может иметь несколько экземпляров.

Интересные статьи...