sealed class i interface w Kotlin — co to jest, składnia i zastosowanie

Autor: IT Sectr Opublikowano: 2026-06-20 Czas czytania: 11 min

sealed class i sealed interface w Kotlin to mechanizmy ograniczonej hierarchii typów, gdzie wszystkie możliwe podklasy są znane na etapie kompilacji. W przeciwieństwie do zwykłych klas abstrakcyjnych, sealed class gwarantuje wyczerpującą obsługę wszystkich wariantów w wyrażeniu when. Zgodnie z dokumentacją JetBrains Kotlin Language Guide (2026), typy sealed stanowią podstawę modelowania stanów, ekranów UI i typów wynikowych w projektach Kotlin.

Najważniejsze

  • sealed — ograniczona hierarchia, gdzie wszystkie podklasy są znane na etapie kompilacji
  • when — wyczerpująca obsługa wszystkich podklas bez obowiązkowego bloku else
  • sealed interface — dodany w Kotlin 1.5 dla elastycznych hierarchii bez ograniczeń dziedziczenia
  • Kompilacja — błąd kompilacji przy niepełnym when dla typów sealed
  • Hierarchia — wszystkie podklasy muszą znajdować się w jednym pliku lub wewnątrz sealed klasy

Czym są sealed class i sealed interface?

sealed class to klasa abstrakcyjna z ograniczeniem: wszystkie jej bezpośrednie podklasy muszą być zadeklarowane w tym samym pliku co sealed class. To ograniczenie sprawia, że hierarchia jest zamknięta (sealed) — żaden kod poza plikiem nie może dodać nowej podklasy.

sealed interface, dodany w Kotlin 1.5, zapewnia tę samą gwarancję, ale z elastycznością interfejsu: sealed interface może być zaimplementowany przez wiele klas, obiektów lub innych interfejsów w jednym pliku. W przeciwieństwie do sealed class, sealed interface nie ma ograniczenia pojedynczego dziedziczenia — klasa może implementować wiele sealed interfejsów jednocześnie.

Według Kotlin Evolution and Roadmap (2026), sealed interface został dodany na prośbę społeczności w celu bardziej elastycznego modelowania. Główną motywacją była możliwość łączenia niezależnych hierarchii typów bez wielodziedziczenia klas.

Składnia sealed class

Deklaracja sealed class zaczyna się od modyfikatora sealed przed class. Podklasy są deklarowane w tym samym pliku.

kotlin
sealed class NetworkResult {
    data class Success(val data: String) : NetworkResult()
    data class Error(val message: String) : NetworkResult()
    object Loading : NetworkResult()
}

Każda podklasa sealed class może mieć własne właściwości i metody. Loading to singleton (object), Success i Error to data class z parametrami. Kompilator zna wszystkie trzy warianty i sprawdza ich kompletność przy użyciu w when.

Zagnieżdżone sealed class

sealed klasy mogą być zagnieżdżone, tworząc wielopoziomowe hierarchie dla złożonych modeli danych bez utraty bezpieczeństwa typów.

kotlin
sealed class UiState {
    object Idle : UiState()
    object Loading : UiState()
    data class Content(val items: List<Item>) : UiState()
    data class Error(val exception: Throwable) : UiState()
}

Składnia sealed interface (Kotlin 1.5+)

sealed interface jest deklarowany podobnie do sealed class, ale pozwala na implementację wielu sealed interfejsów w jednej klasie.

kotlin
sealed interface Action
sealed interface Loggable

data class Navigate(val route: String) : Action, Loggable
data class ShowToast(val text: String) : Action
object GoBack : Action, Loggable

Klasa Navigate implementuje jednocześnie dwa sealed interfejsy — Action i Loggable. Dla sealed class jest to niemożliwe ze względu na ograniczenie pojedynczego dziedziczenia. sealed interface daje elastyczność łączenia niezależnych hierarchii.

Kiedy wybrać sealed interface zamiast sealed class

sealed interface jest preferowany, gdy hierarchia nie wymaga wspólnego stanu ani konstruktora. Zgodnie z JetBrains Kotlin Guidelines (2026), sealed interface powinien być używany domyślnie dla wszystkich nowych hierarchii, gdzie nie jest potrzebny wspólny konstruktor, co czyni kod bardziej elastycznym na przyszłe rozszerzenia.

Wyczerpująca obsługa w when

Główną zaletą typów sealed jest wyczerpująca (exhaustive) obsługa w wyrażeniu when. Kompilator sprawdza, czy wszystkie możliwe podklasy zostały uwzględnione.

kotlin
fun handleResult(result: NetworkResult): String = when (result) {
    is NetworkResult.Success -> "Data: ${result.data}"
    is NetworkResult.Error -> "Error: ${result.message}"
    is NetworkResult.Loading -> "Loading..."
    // else nie jest wymagane — kompilator wie, że wszystkie warianty są obsłużone
}

Jeśli programista doda nową podklasę w sealed hierarchii, ale zapomni obsłużyć ją w when — kompilator zgłosi błąd. To bezpieczeństwo na poziomie typów, niedostępne przy użyciu otwartych hierarchii z gałęzią else.

Według Google Android Developers (2026), sealed klasy to zalecany sposób modelowania stanu UI w Jetpack Compose. Wyczerpująca kontrola when zapobiega sytuacjom, w których programista obsłużył nie wszystkie możliwe warianty wyświetlania ekranu.

Porównanie sealed class z enum class

enum class i sealed class są często mylone, ale mają różne przeznaczenie i możliwości.

Cechysealed classenum class
InstancjeWiele (data class), jedna (object)Dokładnie jedna na stałą
WłaściwościRóżne dla każdej podklasyIdentyczne dla wszystkich stałych
DziedziczenieTak (od sealed class)Nie (implicit final)
KonstruktorMoże mieć parametryTylko wspólny dla wszystkich stałych
HierarchiaOgraniczona, sealedStały zestaw stałych

Wybór między sealed class a enum class zależy od zadania. Jeśli warianty nie niosą dodatkowych danych — użyj enum. Jeśli każdy wariant zawiera unikalne pola — użyj sealed class lub sealed interface.

Praktyczne scenariusze zastosowania

sealed typy są używane w projektach Kotlin do wielu standardowych scenariuszy wymagających modelowania z bezpieczeństwem typów.

Stan UI w Jetpack Compose

Każdy ekran Compose może mieć sealed class UiState, która opisuje wszystkie możliwe stany: Idle, Loading, Content(data), Error(exception). Wyrażenie when gwarantuje, że wszystkie stany są obsłużone.

Wynik zapytań sieciowych

NetworkResult z wariantami Success, Error, Loading to standardowy wzorzec w projektach Kotlin z Retrofit i Ktor. sealed class zapewnia bezpieczną obsługę każdego wyniku zapytania.

Nawigacja w projektach multi-module

sealed interface dla tras nawigacji pozwala modułom deklarować własne trasy, pozostając w ramach jednej hierarchii. Eliminuje to błędy z nieznanymi trasami na etapie kompilacji.

Według KotlinConf (2025), sealed class i sealed interface stanowią podstawę type-safe projektowania w nowoczesnych aplikacjach Kotlin. Łączy się je z data class do modelowania złożonych struktur domenowych bez utraty bezpieczeństwa na etapie kompilacji.

Często zadawane pytania

Gdzie muszą być zadeklarowane podklasy sealed class?

Wszystkie bezpośrednie podklasy sealed class muszą być zadeklarowane w tym samym pliku. Dla sealed interface obowiązuje ta sama zasada — implementacje w jednym pliku.

Czy sealed interface może mieć implementacje w innym pliku?

Nie, zasada jednego pliku obowiązuje również dla sealed interface. Wszystkie implementacje muszą znajdować się w pliku, w którym zadeklarowano sealed interface.

Jaka jest różnica między sealed class a sealed interface?

sealed interface nie ma stanu ani konstruktora, dopuszcza wielokrotną implementację. sealed class może mieć konstruktor i wspólny stan, ale klasa może dziedziczyć tylko jeden sealed class.

Jak sealed klasy pomagają w wyrażeniach when?

Kompilator sprawdza kompletność when: jeśli nie wszystkie podklasy są obsłużone, kod się nie kompiluje. Eliminuje to błędy runtime i czyni kod bezpieczniejszym.

Czy można utworzyć sealed class z konstruktorem?

Tak, sealed class może mieć konstruktor (domyślnie private). Wszystkie podklasy mogą przekazywać parametry do tego konstruktora przez super().

Podsumowanie

  • sealed class — ograniczona hierarchia z podklasami znanymi na etapie kompilacji
  • sealed interface — elastyczna alternatywa (Kotlin 1.5+) z obsługą wielokrotnej implementacji
  • when — wyczerpująca obsługa z kontrolą kompilatora, else nie jest wymagane
  • Jeden plik — wszystkie podklasy i implementacje muszą znajdować się w jednym pliku z sealed typem
  • Modelowanie — stany UI, wyniki sieciowe, nawigacja, systemy zdarzeń
  • Bezpieczeństwo — dodanie nowej podklasy bez obsługi w when powoduje błąd kompilacji
  • Wybór — sealed interface preferowany domyślnie, sealed class gdy potrzebny jest wspólny stan

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również