Sealed Class — was es ist, Funktionsprinzip und Anwendung

Autor: IT Sectr Veröffentlicht: 2026-05-26 Lesezeit: 8 Min.

Sealed Class ist ein spezieller Klassentyp in Kotlin, der die Vererbungshierarchie auf einen festgelegten Satz von Subtypen beschränkt. Alle Subtypen werden in derselben Datei deklariert und sind dem Compiler bekannt, was die Verwendung eines erschöpfenden when-Blocks ohne obligatorischen else-Zweig ermöglicht. Laut Kotlin Docs, 2026 sind versiegelte Klassen ein Schlüsselmechanismus zur Darstellung eingeschränkter Hierarchien wie Zustände, Fehlertypen und UI-Ereignisse.

Wichtige Punkte

  • Sealed Class — Klasse mit einem festgelegten Satz von Subtypen, die in derselben Datei deklariert sind.
  • Exhaustive when — der Compiler prüft, ob alle Subtypen behandelt wurden, und eliminiert vergessene else-Zweige.
  • Sealed interface — Kotlin 1.5+ unterstützt versiegelte Schnittstellen für Mehrfachvererbung.
  • Fehlerhierarchie — sealed class ist der Standardweg für typsichere Fehlerbehandlung in Kotlin.
  • Unterschied zu enum — jeder Subtyp einer sealed class kann einen eindeutigen Zustand und eine unterschiedliche Anzahl von Feldern enthalten.

Was ist Sealed Class?

Sealed Class (versiegelte Klasse) ist eine Klasse in Kotlin, die mit dem sealed-Modifikator markiert ist. Sie definiert eine eingeschränkte Typhierarchie: alle möglichen Subtypen sind in derselben Datei aufgelistet und der Compiler kennt jeden von ihnen. Dies unterscheidet sealed class von einer gewöhnlichen offenen Klasse, deren Subtypen überall deklariert werden können.

Der Hauptzweck einer sealed class ist die typsichere Darstellung einer endlichen Menge von Varianten. Jeder Subtyp kann eine eigene Datenstruktur haben, was sealed class flexibler als enum macht. Zur Laufzeit ist sealed class eine gewöhnliche abstrakte Klasse; der Compiler legt nur zur Compile-Zeit Beschränkungen auf.

Sealed class ist besonders nützlich in der Android-App-Architektur: UI-Zustände, Netzwerkanforderungsergebnisse, Intent-ähnliche Navigationsereignisse und natürlich Fehlerhierarchien sind typische Anwendungsfälle.

Zur Compile-Zeit wird sealed class in eine Sprungtabelle für when-Ausdrücke optimiert, was sie effizienter als if-else-Ketten macht. In Kombination mit data class kann jeder Subtyp nicht nur Zustand, sondern auch Methoden enthalten, was selbstdokumentierende Domänenmodelle ohne Boilerplate-Code ermöglicht.

Sealed class ist auch effektiv für die Darstellung von Zustandsautomaten in mobilen Anwendungen. Jeder Zustand ist ein separater Subtyp mit eindeutigen Parametern, und Übergänge zwischen Zuständen werden durch when-Ausdrücke gesteuert. Der Compiler garantiert, dass alle möglichen Zustände behandelt werden, wodurch Laufzeitfehler beim Ändern des UI-Zustands oder der Geschïtslogik vermieden werden.

Sealed Class vs Enum: Hauptunterschiede

Anfängliche Kotlin-Entwickler verwechseln oft sealed class mit enum, da beide die Menge der Werte einschränken. Es gibt jedoch einen grundlegenden Unterschied: enum ist eine Menge von Konstanten desselben Typs, während sealed class eine Hierarchie verschiedener Typen ist.

Wann enum wählen

Enum ist optimal, wenn alle Varianten Konstanten ohne zusätzliche Struktur sind. Zum Beispiel Wochentage, Bestellstatus oder Aktionstypen ohne Parameter. Jeder enum-Wert ist ein Singleton mit einem festen Namen.

Wann sealed class wählen

Sealed class wird benötigt, wenn jede Variante eigene Daten hat. Zum Beispiel enthält ein Netzwerkfehler einen Antwortcode, ein Parsingfehler enthält Details und ein Autorisierungsfehler enthält eine Nachricht. Jeder Subtyp einer sealed class ist ein separater Typ mit eindeutigen Feldern.

kotlin
// Enum — alle Varianten desselben Typs
enum class Status { LOADING, SUCCESS, ERROR }

// Sealed class — jede Variante mit eigenen Daten
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 vs Sealed Class

Seit Kotlin 1.5 ist es möglich, sealed interface zu deklarieren. Dies erweitert das Versiegelungskonzept auf Schnittstellen: eine sealed interface hat ebenfalls eine feste Menge von Implementierungen, unterstützt aber Mehrfachvererbung.

Wann sealed interface verwenden

Sealed interface ist praktisch, wenn Subtypen mehrere Verträge gleichzeitig implementieren müssen. Zum Beispiel kann ein UI-Ereignis sowohl klickbar als auch verfolgbar sein. Mit sealed class müsste man eine Basisklasse wählen; mit sealed interface implementiert der Subtyp beide.

Einschränkungen von sealed class

Sealed class ist eine Klasse, daher kann jeder Subtyp nur einen Eltern haben. Sealed interface löst dieses Problem, kann aber keinen Zustand enthalten. Die Wahl zwischen ihnen hängt von der Aufgabe ab: wird gemeinsame Logik mit Feldern benötigt — verwende sealed class; wird Vertragsflexibilität benötigt — verwende 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>
}

// Der Subtyp implementiert beide Schnittstellen
data class LoginClicked(
    override val name: String = "login_click",
    override val params: Map<String, Any> = emptyMap()
) : ScreenEvent, AnalyticsEvent

Sealed Class für Fehlerhierarchien in der mobilen Entwicklung

Eine der Hauptanwendungen von sealed class in der mobilen Entwicklung sind typsichere Fehlerhierarchien. Anstatt Ausnahmen verschiedener Typen zu werfen oder eine allgemeine Exception zu verwenden, sammelt sealed class alle möglichen Domänenfehler in einem einzigen Typ.

Wie man eine Fehlerhierarchie aufbaut

Erstelle eine sealed class DomainError und liste alle Fehlertypen als Subtypen auf. Jeder Subtyp enthält nur die Daten, die für diesen bestimmten Fehlertyp relevant sind. Der Compiler garantiert, dass du bei der Fehlerbehandlung keine Variante vergisst.

Beispiel: Authentifizierungsfehlerbehandlung

Betrachten wir eine App mit Autorisierung, bei der verschiedene Fehlerszenarien möglich sind: falsches Passwort, Konto gesperrt, Serverproblem. Sealed class kombiniert sie in einem einzigen Typ mit erschöpfender Behandlung.

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 ->
        "Verbleibende Versuche: ${3 - error.attempts}"
    is AuthError.AccountBlocked ->
        "Zugriff gesperrt bis ${Date(error.until)}"
    is AuthError.NetworkFailure ->
        "Verbindung prüfen: ${error.cause.localizedMessage}"
    AuthError.ServerError ->
        "Server vorübergehend nicht verfügbar"
}

Verwendungsmuster von Sealed Class in Android

Sealed class ist zu einem Standardwerkzeug in der Android-Anwendungsarchitektur geworden. Schauen wir uns drei wichtige Muster an, bei denen sealed class in der mobilen Entwicklung unverzichtbar ist.

  • UI State — Darstellung des Bildschirms als Zustandsautomat: Loading, Content, Error. Jeder Zustand enthält seine eigenen Daten, und sealed class garantiert, dass alle Übergänge behandelt werden.
  • Navigation Event — sealed class anstelle von Navigationskonstanten: jeder Bildschirm ist ein separater Subtyp mit Routenparametern. Der Compiler prüft die Argumenttypen.
  • Action/Intent — das Unidirectional Data Flow-Muster verwendet sealed class, um alle Aktionen darzustellen, die ein Benutzer auf einem Bildschirm ausführen kann.

Erwähnenswert ist auch die Verwendung von sealed class in Clean Architecture. Jede Schicht (data, domain, presentation) verwendet sealed class für ihre Fehlertypen, und Mapper konvertieren eine sealed class in eine andere. Beispielsweise wird DataError aus der Datenschicht in DomainError für die Geschäftslogik und dann in UiState für die Präsentationsschicht gemappt. Dies bewahrt die Typsicherheit auf allen Ebenen der Anwendung und garantiert, dass kein Fehler unbehandelt bleibt.

Testen von Sealed-Class-Hierarchien

Das Testen von sealed class erfordert einen besonderen Ansatz, da jeder Subtyp ein separater Typ mit eigenem Zustand ist. Es wird empfohlen, parametrisierte Tests zu schreiben, die alle Subtypen der sealed class durchlaufen. Dies garantiert, dass when-Ausdrücke alle Varianten abdecken, einschließlich neuer, die bei der Erweiterung der Hierarchie hinzugefügt werden.

Für UI-Tests ermöglicht sealed class als UiState die Überprüfung der Anzeige jedes Zustands: Loading zeigt einen Spinner, Content zeigt Daten, Error zeigt eine Fehlermeldung. Da sealed class endlich ist, gibt die Testabdeckung aller Zustände vollständiges Vertrauen in die Korrektheit der UI-Logik.

Häufige Fehler bei der Arbeit mit Sealed Class

Trotz der Einfachheit des Konzepts machen Entwickler regelmäßig Fehler beim Entwurf von sealed-class-Hierarchien. Schauen wir uns die Hauptprobleme an und wie man sie vermeidet.

  • Subtypen in verschiedenen Dateien — der Compiler erlaubt keine Deklaration einer sealed class, wenn sich die Subtypen außerhalb der Datei befinden. Diese Einschränkung garantiert einen erschöpfenden when.
  • Mischen von sealed und open — eine sealed class kann nicht gleichzeitig open sein. Wenn eine erweiterbare Hierarchie benötigt wird, verwende eine gewöhnliche abstrakte Klasse, aber du opferst die Erschöpfendheit.
  • Übermäßige Verschachtelung — sealed class in sealed class erzeugt eine tiefe Hierarchie, die schwer zu warten ist. Für einfache Szenarien reichen zwei Ebenen aus.
  • Vergessener else in when — wenn eine sealed class aus einer Bibliothek keine Erschöpfendheit bietet, warnt der Compiler nicht über einen fehlenden Zweig. Füge else nur bewusst hinzu.

Häufig gestellte Fragen

Kann eine sealed class abstrakte Methoden haben?

Ja, eine sealed class kann abstrakte Methoden enthalten, und jeder Subtyp muss sie implementieren. Dies ist praktisch, wenn alle Varianten eine gemeinsame Schnittstelle bieten sollen, aber mit unterschiedlicher Ausführungslogik.

Sind sealed classes in Java verfügbar?

In Java 17+ wurden versiegelte Klassen und Schnittstellen mit dem sealed-Modifikator eingeführt. Android unterstützt Java 17 derzeit teilweise, aber in Kotlin-Projekten ist sealed class seit Kotlin 1.0 ohne Einschränkungen verfügbar.

Kann eine sealed class von einer anderen sealed class erben?

Ja, eine sealed class kann ein Subtyp einer anderen sein. Die sealed-class-Hierarchie bleibt endlich: der Compiler kennt alle Subtypen auf jeder Ebene. Dies ermöglicht den Aufbau detaillierter Fehlerklassifikationen.

Beeinflusst sealed class die Leistung?

Sealed class verursacht keine Laufzeit-Überhead. Der Compiler optimiert when-Ausdrücke mit sealed classes in Sprungtabellen (tableswitch), die schneller sind als if-else-Ketten. Die Leistung ist identisch mit enum.

Wie testet man sealed-class-Hierarchien?

Jeder Subtyp einer sealed class wird separat getestet. Da sealed class endlich ist, kann man einen parametrisierten Test schreiben, der alle Varianten durchläuft. Dies bietet eine vollständige Abdeckung der when-Block-Zweige.

Zusammenfassung

  • Sealed class — Klasse mit einem festgelegten Satz von Subtypen, die in einer Datei deklariert sind, was eine erschöpfende when-Analyse zur Compile-Zeit ermöglicht.
  • Jeder Subtyp einer sealed class kann eine eigene Datenstruktur haben — dies ist der Hauptunterschied zu enum, wo alle Varianten Konstanten desselben Typs sind.
  • Sealed interface (Kotlin 1.5+) unterstützt Mehrfachvererbung, sealed class unterstützt nur Einfachvererbung. Die Wahl hängt vom Bedarf an gemeinsamem Zustand ab.
  • Sealed class ist der Standardmechanismus für typsichere Fehlerhierarchien in Kotlin: jeder Fehlertyp ist ein separater Subtyp mit relevanten Feldern.
  • Hauptmuster in Android: UI State, Navigation Event und Action/Intent — basieren auf sealed class, um Vollständigkeit der Behandlung zu gewährleisten.
  • Vermeide Subtypen in verschiedenen Dateien, übermäßige Verschachtelung und das Mischen von sealed mit open — dies verletzt den Vertrag einer endlichen Hierarchie.

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch