W tym artykule dowiesz się o klasie Sealed, jak są one tworzone i kiedy ich używać na przykładach.
Klasy zapieczętowane są używane, gdy wartość może mieć tylko jeden z typów z ograniczonego zestawu (ograniczone hierarchie).
Zanim przejdziemy do szczegółów na temat zapieczętowanych klas, przyjrzyjmy się, jaki problem rozwiązują. Weźmy przykład (zaczerpnięty z oficjalnej strony Kotlin - artykuł o zapieczętowanych klasach):
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") )
W powyższym programie klasa bazowa Expr ma dwie klasy pochodne Const (reprezentuje liczbę) i Sum (reprezentuje sumę dwóch wyrażeń). Tutaj obowiązkowe jest użycie else
brancha jako warunku domyślnego w wyrażeniu when.
Teraz, jeśli wyprowadzisz nową podklasę z Expr
klasy, kompilator nie wykryje niczego, ponieważ else
gałąź obsługuje to, co może prowadzić do błędów. Byłoby lepiej, gdyby kompilator wystawił błąd podczas dodawania nowej podklasy.
Aby rozwiązać ten problem, możesz użyć zapieczętowanej klasy. Jak wspomniano, klasa zapieczętowana ogranicza możliwość tworzenia podklas. A kiedy obsługujesz wszystkie podklasy zapieczętowanej klasy w when
wyrażeniu, nie jest konieczne używanie else
branch.
Aby utworzyć zapieczętowaną klasę, używany jest modyfikator zapieczętowany. Na przykład,
klasa zamknięta Wyr
Przykład: klasa zamknięta
Oto jak możesz rozwiązać powyższy problem za pomocą zapieczętowanej klasy:
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 )
Jak widać, nie ma else
gałęzi. Jeśli wyprowadzisz nową podklasę z Expr
klasy, kompilator będzie narzekał, chyba że podklasa jest obsługiwana w when
wyrażeniu.
Kilka ważnych uwag
- Wszystkie podklasy klasy zapieczętowanej muszą być zadeklarowane w tym samym pliku, w którym zadeklarowano klasę zapieczętowaną.
- Klasa zapieczętowana jest sama w sobie abstrakcyjna i nie można z niej tworzyć instancji obiektów.
- Nie można tworzyć nieprywatnych konstruktorów zapieczętowanej klasy; ich konstruktory są
private
domyślnie.
Różnica między klasą Enum i Sealed
Klasa wyliczenia i klasa zapieczętowana są dość podobne. Zestaw wartości dla typu wyliczenia jest również ograniczony jak klasa zapieczętowana.
Jedyną różnicą jest to, że wyliczenie może mieć tylko jedno wystąpienie, podczas gdy podklasa zapieczętowanej klasy może mieć wiele wystąpień.