Sealed Class — mi ez, működési elv és alkalmazása

Szerző: IT Sectr Megjelenés: 2026-05-26 Olvasási idő: 8 perc

Sealed Class — egy speciális osztálytípus Kotlinban, amely az öröklődési hierarchiát rögzített altípuskészletre korlátozza. Az összes örökös ugyanabban a fájlban van deklarálva és ismert a fordító számára, ami lehetővé teszi a kimerítő when blokk használatát kötelező else ág nélkül. A Kotlin Docs, 2026 szerint a lezárt osztályok kulcsfontosságú mechanizmusok a korlátozott hierarchiák, például állapotok, hibatípusok és UI-események ábrázolására.

Főbb pontok

  • Sealed Class — osztály rögzített örököskészlettel, ugyanabban a fájlban deklarálva.
  • Exhaustive when — a fordító ellenőrzi, hogy az összes altípus feldolgozásra került, kiküszöbölve az elfelejtett else ágakat.
  • Sealed interface — Kotlin 1.5+ támogatja a lezárt interfészeket többszörös öröklődéshez.
  • Hiba hierarchia — a sealed class a típusbiztos hibakezelés szabványos módja Kotlinban.
  • Különbség az enum-tól — a sealed class minden örököse egyedi állapotot és eltérő számú mezőt tartalmazhat.

Mi az a Sealed Class?

Sealed Class (lezárt osztály) — ez egy Kotlinban sealed módosítóval jelölt osztály. Korlátozott típushierarchiát határoz meg: az összes lehetséges örökös ugyanabban a fájlban van felsorolva, és a fordító tud mindegyikről. Ez különbözteti meg a sealed class-t a szokásos nyílt osztálytól, amelynek örökösei bárhol deklarálhatók.

A sealed class fő célja — véges varánskészlet típusbiztos ábrázolása. Minden örökös saját adatstruktúrával rendelkezhet, ami rugalmasabbá teszi a sealed class-t az enum-nál. Futásidőben a sealed class egy szokásos absztrakt osztály, a fordító csak fordítási időben alkalmaz korlátozásokat.

A sealed class különösen hasznos az Android architektúrában: UI-állapotok, hálózati kérések eredményei, Intent-szerű navigációs események és természetesen hiba hierarchiák — tipikus alkalmazási forgatókönyvek.

Fordításkor a sealed class egy átmeneti táblává optimalizálódik a when kifejezésekhez, ami hatékonyabbá teszi az if-else láncoknál. Data class-szal kombinálva minden örökös nemcsak állapotot, hanem metódusokat is tartalmazhat, ami lehetővé teszi öndokumentáló domain modellek építését boilerplate kód nélkül.

A sealed class hatékony a véges állapotgépek (state machine) ábrázolására is mobilalkalmazásokban. Minden állapot — külön örökös egyedi paraméterekkel, az állapotok közötti átmenetek pedig a when kifejezésen keresztül vezérelhetők. A fordító garantálja, hogy az összes lehetséges állapot feldolgozásra került, ami kiküszöböli a futásidejű hibákat az UI állapot vagy üzleti logika változásakor.

Sealed Class és Enum: fő különbségek

A kezdő Kotlin fejlesztők gyakran összekeverik a sealed class-t az enum-mal, mivel mindkettő korlátozza az értékkészletet. Azonban alapvető különbség van közöttük: az enum — azonos típusú konstansok halmaza, a sealed class — különböző típusok hierarchiája.

Mikor válasszuk az enum-ot

Enum optimális, ha minden változat konstans további struktúra nélkül. Például a hét napjai, rendelési státuszok vagy paraméter nélküli akciótípusok. Minden enum érték egy singleton rögzített névvel.

Mikor válasszuk a sealed class-t

Sealed class akkor szükséges, ha minden változatnak saját adatai vannak. Például a hálózati hiba válaszkódot, a parsing hiba részleteket, az autorizációs hiba pedig üzenetet tartalmaz. A sealed class minden örököse egy külön típus egyedi mezőkkel.

kotlin
// Enum — egy típus összes változata
enum class Status { LOADING, SUCCESS, ERROR }

// Sealed class — minden változat saját adatokkal
sealed class UiState<out T> {
    object Loading : UiState<Nothing>()
    data class Success<T>(val data: T) : UiState<T>()
    data class Error(val message: String) : UiState<Nothing>()
}

Sealed Interface kontra Sealed Class

Kotlin 1.5-től lehetőség van sealed interface deklarálására. Ez kiterjeszti a sealed koncepciót interfészekre: a sealed interface is rögzített implementációkészlettel rendelkezik, de támogatja a többszörös öröklődést.

Mikor használjuk a sealed interface-t

Sealed interface akkor kényelmes, ha az örökösöknek egyszerre több szerződést kell implementálniuk. Például egy UI esemény lehet egyszerre kattintható és követhető. Sealed class esetén egy alaposztályt kellene választani, sealed interface esetén az örökös mindkettőt implementálja.

A sealed class korlátai

Sealed class egy osztály, így minden örökös csak egy szülővel rendelkezhet. A sealed interface megoldja ezt a problémát, de nem tárolhat állapotot. A köztük való választás a feladattól függ: közös logika mezőkkel szükséges — sealed class, szerződések rugalmassága szükséges — sealed interface.

kotlin
sealed interface ScreenEvent {
    data class Refresh(val force: Boolean) : ScreenEvent
    data class Navigate(val route: String) : ScreenEvent
    data class ShowError(val toast: String) : ScreenEvent
}

sealed interface AnalyticsEvent {
    val name: String
    val params: Map<String, Any>
}

// Az örökös mindkét interfészt implementálja
data class LoginClicked(
    override val name: String = "login_click",
    override val params: Map<String, Any> = emptyMap()
) : ScreenEvent, AnalyticsEvent

Sealed Class hiba hierarchiához mobilfejlesztésben

A sealed class egyik fő alkalmazása a mobilfejlesztésben — típusbiztos hiba hierarchia. Ahelyett, hogy különböző típusú kivételeket dobálnánk vagy általános Exception-t használnánk, a sealed class az összes lehetséges domain hibát egyetlen típusba gyűjti.

Hogyan építsünk hiba hierarchiát

Hozzon létre egy DomainError sealed class-t és sorolja fel az összes meghibásodási típust örökösként. Minden örökös csak azokat az adatokat tartalmazza, amelyek értelmesek az adott hibatípushoz. A fordító garantálja, hogy a hiba feldolgozásakor nem felejt el egyetlen változatot sem.

Példa: hitelesítési hibák kezelése

Tekintsünk egy autorizációs alkalmazást, ahol különböző meghibásodási forgatókönyvek lehetségesek: helytelen jelszó, fiók zárolása, szerver probléma. A sealed class egyetlen típussá egyesíti őket kimerítő kezeléssel.

kotlin
sealed class AuthError {
    data class InvalidCredentials(
        val attempts: Int
    ) : AuthError()

    data class AccountBlocked(
        val until: Long
    ) : AuthError()

    data class NetworkFailure(
        val cause: Throwable
    ) : AuthError()

    object ServerError : AuthError()
}

fun handleError(error: AuthError): String = when (error) {
    is AuthError.InvalidCredentials ->
        "Hátralévő próbálkozások: ${3 - error.attempts}"
    is AuthError.AccountBlocked ->
        "Hozzáférés letiltva ${Date(error.until)}-ig"
    is AuthError.NetworkFailure ->
        "Ellenőrizze a kapcsolatot: ${error.cause.localizedMessage}"
    AuthError.ServerError ->
        "A szerver átmenetileg nem elérhető"
}

Sealed Class használati minták Androidban

Sealed class szabványos eszközzé vált az Android alkalmazások architektúrájában. Vizsgáljunk meg három kulcsfontosságú mintát, ahol a sealed class nélkülözhetetlen a mobilfejlesztésben.

  • UI State — a képernyő ábrázolása véges állapotgépként: Loading, Content, Error. Minden állapot saját adatokat tartalmaz, a sealed class pedig garantálja, hogy az összes átmenet feldolgozásra került.
  • Navigation Event — sealed class a navigációs konstansok helyett: minden képernyő külön örökös útvonal paraméterekkel. A fordító ellenőrzi az argumentumok típusait.
  • Action/Intent — az Unidirectional Data Flow minta sealed class-t használ a felhasználó által a képernyőn végrehajtható összes művelet ábrázolására.

Külön említést érdemel a sealed class alkalmazása a Clean Architecture-ban. Minden réteg (data, domain, presentation) saját hibatípusaihoz használ sealed class-t, a mapper-ek pedig az egyik sealed class-t alakítják át a másikba. Például a DataError az adatrétegből DomainError-ra az üzleti logikához, majd UiState-re a prezentációs réteghez. Ez megőrzi a típusbiztonságot az alkalmazás minden szintjén, és garantálja, hogy egyetlen hiba sem marad feldolgozatlan.

Sealed class hierarchiák tesztelése

Tesztelés sealed class esetén különleges megközelítést igényel, mivel minden örökös egy külön típus saját állapottal. Javasolt paraméterezett tesztek írása, amelyek a sealed class összes örökösén áthaladnak. Ez garantálja, hogy a when kifejezések az összes változatot lefedik, beleértve a hierarchia bővítésekor hozzáadott újakat is.

UI tesztekhez a sealed class mint UiState lehetővé teszi az egyes állapotok megjelenítésének ellenőrzését: Loading spinner-t mutat, Content — adatokat, Error — hibaüzenetet. Mivel a sealed class véges, az összes állapot tesztlefedettsége teljes bizonyosságot ad az UI logika helyességéről.

Gyakori hibák a Sealed Class használatánál

A koncepció egyszerűsége ellenére a fejlesztők rendszeresen hibáznak a sealed class hierarchiák tervezésénél. Vizsgáljuk meg a fő problémákat és az elkerülésük módjait.

  • Örökösök különböző fájlokban — a fordító nem engedi a sealed class deklarálását, ha az örökösök a fájlon kívül vannak. Ez a korlátozás garantálja a kimerítő when-t.
  • Sealed és open keverése — a sealed class nem lehet egyszerre open. Ha bővíthető hierarchia szükséges, használjon szokásos abstract class-t, de feláldozza a kimerítőséget.
  • Túlzott beágyazottság — sealed class sealed class-on belül mély hierarchiát hoz létre, amelyet nehéz karbantartani. Egyszerű forgatókönyvekhez két szint elegendő.
  • Elfelejtett else a when-ben — ha a könyvtárból származó sealed class nem rendelkezik kimerítőséggel, a fordító nem figyelmeztet a kihagyott ágról. Az else-t csak tudatosan adja hozzá.

Gyakran Ismételt Kérdések

Lehetnek a sealed class-nak absztrakt metódusai?

Igen, a sealed class tartalmazhat absztrakt metódusokat, és minden örökös köteles azokat implementálni. Ez akkor kényelmes, ha minden változatnak egységes interfészt kell biztosítania, de eltérő végrehajtási logikával.

Elérhetők a sealed class-ok Java-ban?

Java 17+-ben megjelentek a lezárt osztályok és interfészek a sealed módosítóval. Az Android jelenleg részben támogatja a Java 17-et, de Kotlin projektekben a sealed class Kotlin 1.0 óta korlátozások nélkül elérhető.

Örökölhet-e egy sealed class egy másik sealed class-tól?

Igen, egy sealed class örököse lehet egy másiknak. A sealed class hierarchia véges marad: a fordító ismeri az összes örököst minden szinten. Ez lehetővé teszi részletes hibaosztályozások építését.

Befolyásolja-e a sealed class a teljesítményt?

A Sealed class nem hoz létre többletköltséget futásidőben. A fordító a sealed class-okkal használt when kifejezéseket átmeneti táblákká (tableswitch) optimalizálja, ami gyorsabb, mint az if-else láncok. A teljesítmény megegyezik az enum-éval.

Hogyan teszteljük a sealed class hierarchiákat?

A sealed class minden örökösét külön teszteljük. Mivel a sealed class véges, írhatunk egy paraméterezett tesztet, amely az összes változaton áthalad. Ez teljes lefedettséget biztosít a when blokkok ágaira.

Összefoglalás

  • Sealed class — osztály rögzített örököskészlettel, egy fájlban deklarálva, ami kimerítő when elemzést biztosít fordítási időben.
  • A sealed class minden örököse rendelkezhet saját adatstruktúrával — ez a fő különbség az enum-tól, ahol minden változat azonos típusú konstans.
  • Sealed interface (Kotlin 1.5+) támogatja a többszörös öröklődést, a sealed class — csak az egyszeres öröklődést. A választás a közös állapot iránti igénytől függ.
  • A sealed class — szabványos mechanizmus a típusbiztos hiba hierarchiához Kotlinban: minden meghibásodási típus külön örökös a megfelelő mezőkkel.
  • Fő minták Androidban: UI State, Navigation Event és Action/Intent — a sealed class-ra épülnek a feldolgozás teljességének garantálásához.
  • Kerülje az örökösöket különböző fájlokban, a túlzott beágyazottságot és a sealed open-nel való keverését — ez megsérti a véges hierarchia szerződését.

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is