В тази статия ще научите за Sealed class, как се създават и кога да ги използвате с помощта на примери.
Запечатаните класове се използват, когато стойност може да има само един от типовете от ограничен набор (ограничени йерархии).
Преди да влезем в подробности за запечатаните класове, нека разгледаме какъв проблем решават. Да вземем пример (взето от официалния уебсайт на Kotlin - статия за запечатани класове):
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
клон за условие по подразбиране в когато израз.
Сега, ако извлечете нов подклас от Expr
клас, компилаторът няма да открие нищо, тъй като else
клонът го обработва, което може да доведе до грешки. Би било по-добре, ако компилаторът издаде грешка, когато добавихме нов подклас.
За да разрешите този проблем, можете да използвате запечатан клас. Както споменахме, запечатаният клас ограничава възможността за създаване на подкласове. И когато обработвате всички подкласове на запечатан клас в when
израз, не е необходимо да използвате else
клон.
За създаване на запечатан клас се използва запечатан модификатор. Например,
запечатан клас 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 и запечатан клас
Класът Enum и запечатаният клас са доста сходни. Наборът от стойности за тип преброяване също е ограничен като запечатан клас.
Единствената разлика е, че enum може да има само един екземпляр, докато подкласът на запечатан клас може да има множество екземпляри.