Sealed Class — ce este, principiul de funcționare și aplicarea

Autor: IT Sectr Publicat: 2026-05-26 Timp de citire: 8 min

Sealed Class — un tip special de clasă în Kotlin care limitează ierarhia de moștenire la un set fix de subtipuri. Toți moștenitorii sunt declarați în același fișier și sunt cunoscuți de compilator, ceea ce permite utilizarea unui bloc when exhaustiv fără o ramură else obligatorie. Potrivit Kotlin Docs, 2026, clasele sigilate sunt mecanismul cheie pentru reprezentarea ierarhiilor limitate, cum ar fi stările, tipurile de erori și evenimentele UI.

Principalele aspecte

  • Sealed Class — clasă cu un set fix de moștenitori declarați în același fișier.
  • Exhaustive when — compilatorul verifică dacă toate subtipurile au fost procesate, eliminând ramurile else uitate.
  • Sealed interface — Kotlin 1.5+ suportă interfețe sigilate pentru moștenire multiplă.
  • Ierarhia erorilor — sealed class este modalitatea standard de gestionare tip-securizată a erorilor în Kotlin.
  • Diferența față de enum — fiecare moștenitor al sealed class poate conține o stare unică și un număr diferit de câmpuri.

Ce este Sealed Class?

Sealed Class (clasă sigilată) — este o clasă în Kotlin marcată cu modificatorul sealed. Ea definește o ierarhie limitată de tipuri: toți moștenitorii posibili sunt enumerați în același fișier, iar compilatorul știe despre fiecare dintre ei. Aceasta deosebește sealed class de o clasă deschisă obișnuită, ai cărei moștenitori pot fi declarați oriunde.

Scopul principal al sealed class este reprezentarea tip-securizată a unui set finit de variante. Fiecare moștenitor poate avea propria structură de date, ceea ce face sealed class mai flexibil decât enum. La runtime, sealed class este o clasă abstractă obișnuită, compilatorul impunând restricții doar în faza de compilare.

Sealed class este deosebit de util în arhitectura Android a aplicațiilor: stări UI, rezultate ale cererilor de rețea, evenimente de navigare de tip Intent și, desigur, ierarhii de erori — scenarii tipice de aplicare.

La compilare, sealed class este optimizat într-un tabel de tranziții pentru expresiile when, ceea ce îl face mai performant decât lanțurile if-else. În combinație cu data class, fiecare moștenitor poate conține nu doar stare, ci și metode, permițând construirea de modele de domeniu auto-documentate fără cod boilerplate.

Sealed class este eficient și pentru reprezentarea automatelor finite (state machine) în aplicațiile mobile. Fiecare stare — un moștenitor separat cu parametri unici, iar tranzițiile între stări sunt controlate prin expresia when. Compilatorul garantează că toate stările posibile au fost procesate, ceea ce elimină erorile de runtime la modificarea stării UI sau a logicii de business.

Sealed Class și Enum: diferențe cheie

Dezvoltatorii începători în Kotlin confundă adesea sealed class cu enum, deoarece ambele limitează setul de valori. Însă există o diferență fundamentală între ele: enum — este un set de constante de același tip, sealed class — o ierarhie de tipuri diferite.

Când să alegeți enum

Enum este optim atunci când toate variantele sunt constante fără structură suplimentară. De exemplu, zilele săptămânii, stările comenzii sau tipurile de acțiuni fără parametri. Fiecare valoare enum este un singleton cu un nume fix.

Când să alegeți sealed class

Sealed class este necesar atunci când fiecare variantă are propriile date. De exemplu, o eroare de rețea conține codul de răspuns, o eroare de parsare — detalii, iar o eroare de autorizare — un mesaj. Fiecare moștenitor al sealed class este un tip separat cu câmpuri unice.

kotlin
// Enum — toate variantele unui singur tip
enum class Status { LOADING, SUCCESS, ERROR }

// Sealed class — fiecare variantă cu propriile date
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 versus Sealed Class

Începând cu Kotlin 1.5, există posibilitatea de a declara sealed interface. Aceasta extinde conceptul sealed la interfețe: sealed interface are de asemenea un set fix de implementări, dar suportă moștenirea multiplă.

Când să utilizați sealed interface

Sealed interface este convenabil atunci când moștenitorii trebuie să implementeze mai multe contracte simultan. De exemplu, un eveniment UI poate fi simultan clickabil și urmăribil. Cu sealed class ar trebui să alegeți o singură clasă de bază, cu sealed interface moștenitorul le implementează pe ambele.

Limitările sealed class

Sealed class este o clasă, deci fiecare moștenitor poate avea doar un părinte. Sealed interface rezolvă această problemă, dar nu poate conține stare. Alegerea dintre ele depinde de sarcină: aveți nevoie de logică comună cu câmpuri — sealed class, aveți nevoie de flexibilitate a contractelor — 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>
}

// Moștenitorul implementează ambele interfețe
data class LoginClicked(
    override val name: String = "login_click",
    override val params: Map<String, Any> = emptyMap()
) : ScreenEvent, AnalyticsEvent

Sealed Class pentru ierarhia erorilor în dezvoltarea mobilă

Una dintre principalele utilizări ale sealed class în dezvoltarea mobilă — ierarhia tip-securizată a erorilor. În loc să aruncați excepții de diferite tipuri sau să utilizați Exception generic, sealed class colectează toate erorile posibile de domeniu într-un singur tip.

Cum să construiți o ierarhie de erori

Creați un sealed class DomainError și enumerați toate tipurile de defecțiuni ca moștenitori. Fiecare moștenitor conține doar datele care au sens pentru acel tip de eroare. Compilatorul garantează că la procesarea erorii nu veți uita nici o variantă.

Exemplu: gestionarea erorilor de autentificare

Să considerăm o aplicație cu autentificare, unde sunt posibile diferite scenarii de defecțiune: parolă incorectă, blocarea contului, problemă cu serverul. Sealed class le unește într-un singur tip cu gestionare exhaustivă.

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 ->
        "Au rămas încercări: ${3 - error.attempts}"
    is AuthError.AccountBlocked ->
        "Acces blocat până la ${Date(error.until)}"
    is AuthError.NetworkFailure ->
        "Verificați conexiunea: ${error.cause.localizedMessage}"
    AuthError.ServerError ->
        "Serverul este temporar indisponibil"
}

Modele de utilizare Sealed Class în Android

Sealed class a devenit un instrument standard în arhitectura aplicațiilor Android. Să examinăm trei modele cheie în care sealed class este de neînlocuit în dezvoltarea mobilă.

  • UI State — reprezentarea ecranului ca automat finit: Loading, Content, Error. Fiecare stare conține propriile date, iar sealed class garantează că toate tranzițiile sunt procesate.
  • Navigation Event — sealed class în loc de constante de navigare: fiecare ecran este un moștenitor separat cu parametri de rută. Compilatorul verifică tipurile argumentelor.
  • Action/Intent — modelul Unidirectional Data Flow utilizează sealed class pentru a reprezenta toate acțiunile pe care utilizatorul le poate efectua pe ecran.

Separat, merită menționată aplicarea sealed class în Clean Architecture. Fiecare strat (data, domain, presentation) utilizează sealed class pentru propriile tipuri de erori, iar mapperii transformă un sealed class în altul. De exemplu, DataError din stratul de date este mapat în DomainError pentru logica de business, apoi în UiState pentru stratul de prezentare. Aceasta păstrează tip-securitatea la toate nivelurile aplicației și garantează că nici o eroare nu rămâne neprocesată.

Testarea ierarhiilor sealed class

Testarea sealed class necesită o abordare specială, deoarece fiecare moștenitor este un tip separat cu propria stare. Se recomandă scrierea de teste parametrizate care parcurg toți moștenitorii sealed class. Aceasta garantează că expresiile when acoperă toate variantele, inclusiv pe cele noi adăugate la extinderea ierarhiei.

Pentru testele UI, sealed class ca UiState permite verificarea afișării fiecărei stări: Loading arată un spinner, Content — date, Error — un mesaj de eroare. Deoarece sealed class este finit, acoperirea testelor pentru toate stările oferă încredere completă în corectitudinea logicii UI.

Greșeli tipice la lucrul cu Sealed Class

În ciuda simplității conceptului, dezvoltătorii fac frecvent greșeli la proiectarea ierarhiilor sealed class. Să examinăm principalele probleme și modalitățile de a le evita.

  • Moștenitori în fișiere diferite — compilatorul nu va permite declararea sealed class dacă moștenitorii se află în afara fișierului. Această restricție garantează when exhaustiv.
  • Amestecarea sealed și open — sealed class nu poate fi open simultan. Dacă aveți nevoie de o ierarhie extensibilă, utilizați un abstract class obișnuit, dar veți sacrifica exhaustivitatea.
  • Încuibare excesivă — sealed class în sealed class creează o ierarhie profundă dificil de întreținut. Pentru scenarii simple, două niveluri sunt suficiente.
  • Else uitat în when — dacă sealed class dintr-o bibliotecă nu are exhaustivitate, compilatorul nu va avertiza despre ramura omisă. Adăugați else doar conștient.

Întrebări frecvente

Poate sealed class să aibă metode abstracte?

Da, sealed class poate conține metode abstracte, iar fiecare moștenitor este obligat să le implementeze. Este convenabil când toate variantele trebuie să ofere o interfață comună, dar cu logică de execuție diferită.

Sunt disponibile sealed class în Java?

În Java 17+ au apărut clase și interfețe sigilate cu modificatorul sealed. Android suportă parțial Java 17 deocamdată, dar în proiectele Kotlin sealed class este disponibil din Kotlin 1.0 fără restricții.

Poate sealed class să moștenească de la un alt sealed class?

Da, un sealed class poate fi moștenitorul altuia. Ierarhia sealed class rămâne finită: compilatorul cunoaște toți moștenitorii la fiecare nivel. Aceasta permite construirea de clasificări detaliate ale erorilor.

Influențează sealed class performanța?

Sealed class nu creează cheltuieli suplimentare la runtime. Compilatorul optimizează expresiile when cu sealed class în tabele de tranziție (tableswitch), ceea ce este mai rapid decât lanțurile if-else. Performanța este identică cu enum.

Cum se testează ierarhiile sealed class?

Fiecare moștenitor al sealed class se testează separat. Deoarece sealed class este finit, se poate scrie un test parametrizat care parcurge toate variantele. Aceasta oferă acoperire completă a ramurilor blocurilor when.

Concluzii

  • Sealed class — clasă cu un set fix de moștenitori declarați într-un singur fișier, oferind analiză exhaustivă when la compilare.
  • Fiecare moștenitor al sealed class poate avea propria structură de date — principala diferență față de enum, unde toate variantele sunt constante de același tip.
  • Sealed interface (Kotlin 1.5+) suportă moștenire multiplă, sealed class — doar moștenire simplă. Alegerea depinde de necesitatea unei stări comune.
  • Sealed class — mecanism standard pentru ierarhia tip-securizată a erorilor în Kotlin: fiecare tip de defecțiune — un moștenitor separat cu câmpuri relevante.
  • Principalele modele în Android: UI State, Navigation Event și Action/Intent — se bazează pe sealed class pentru garantarea completitudinii procesării.
  • Evitați moștenitorii în fișiere diferite, încuibarea excesivă și amestecarea sealed cu open — acestea încalcă contractul ierarhiei finite.

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și