V tomto článku sa dozviete o lekciách Sealed, ako sú vytvorené a kedy ich treba pomocou príkladov použiť.
Uzavreté triedy sa používajú, keď hodnota môže mať iba jeden z typov z obmedzenej množiny (obmedzené hierarchie).
Predtým, ako sa pozrieme na podrobnosti o zapečatených triedach, poďme preskúmať, aký problém riešia. Zoberme si príklad (prevzatý z oficiálneho webu Kotlin - článok 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") )
Vo vyššie uvedenom programe má základná trieda Expr dve odvodené triedy Const (predstavuje číslo) a Sum (predstavuje súčet dvoch výrazov). Tu je povinné použiť else
vetvu ako predvolenú podmienku vo výraze.
Teraz, ak odvodíte novú podtriedu z Expr
triedy, kompilátor nezistí nič, pretože else
ju obsluhuje pobočka, čo môže viesť k chybám. Bolo by lepšie, keby kompilátor vydal chybu, keď sme pridali novú podtriedu.
Ak chcete vyriešiť tento problém, môžete použiť zapečatenú triedu. Ako už bolo spomenuté, zapečatená trieda obmedzuje možnosť vytvárania podtried. A keď vo when
výraze narábate so všetkými podtriedami zapečatenej triedy , nie je potrebné používať else
vetvu.
Na vytvorenie zapečatenej triedy sa používa zapečatený modifikátor. Napríklad,
zapečatená trieda Expr
Príklad: zapečatená trieda
Tu je príklad, ako môžete vyriešiť vyššie uvedený problém pomocou zapečatenej triedy:
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 )
Ako vidíte, neexistuje žiadna else
pobočka. Ak odvodíte novú podtriedu z Expr
triedy, kompilátor sa bude sťažovať, pokiaľ sa s podtriedou vo when
výraze nespracuje.
Niekoľko dôležitých poznámok
- Všetky podtriedy zapečatenej triedy musia byť deklarované v rovnakom súbore, kde je vyhlásená zapečatená trieda.
- Zapečatená trieda je sama o sebe abstraktná a nemôžete z nej vytvoriť inštanciu.
- Nemôžete vytvoriť neverejné konštruktory zapečatenej triedy; ich konštruktory sú
private
predvolene.
Rozdiel medzi Enum a Sealed Class
Trieda Enum a zapečatená trieda sú si dosť podobné. Množina hodnôt pre typ enum je tiež obmedzená ako zapečatená trieda.
Jediný rozdiel je v tom, že enum môže mať iba jednu inštanciu, zatiaľ čo podtrieda zapečatenej triedy môže mať viac inštancií.