Kotlin Academy · Les

Sealed hiërarchieën nesten en combineren

Bouw complexe state machines door sealed typen te nesten.

Les 4 van 413 stappen

Sealed hiërarchieën nesten en combineren is een gratis Kotlin Academy-les op CoddyKit. Dit is les 4 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Kotlin Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Kotlin Academy bevat in totaal 4 lessen.

Statusbomen samenstellen

Statussen uit de praktijk hebben vaak meerdere dimensies. Nest sealed typen of combineer afzonderlijke hiërarchieën om complexe domeinen overzichtelijk te modelleren.

Geneste sealed klasse

Declareer onderliggende sealed typen binnen een bovenliggend sealed type. De compiler dwingt nog steeds volledigheid in de volledige boom af.

sealed class UiState {
    object Loading : UiState()
    sealed class Loaded : UiState() {
        data class Success(val items: List<String>) : Loaded()
        data class Empty(val message: String) : Loaded()
    }
    data class Error(val msg: String) : UiState()
}
fun render(s: UiState) = when (s) {
    UiState.Loading -> "loading"
    is UiState.Loaded.Success -> "${s.items.size} items"
    is UiState.Loaded.Empty -> "empty: ${s.message}"
    is UiState.Error -> "err: ${s.msg}"
}
fun main() {
    println(render(UiState.Loaded.Success(listOf("a", "b"))))
}

Sealed interfaces voor mixins

Gebruik sealed interfaces wanneer een status meerdere onafhankelijke aspecten heeft — elk aspect is een andere interface.

sealed interface Authenticated
data class User(val id: Int) : Authenticated
object Guest
sealed interface Permission
object Read : Permission
object Write : Permission
fun describe(a: Authenticated, p: Permission): String = when {
    a is User && p is Write -> "user ${a.id} can write"
    a is User -> "user ${a.id} can read"
    else -> "?"
}
fun main() {
    println(describe(User(1), Write))
}

Hiërarchieën combineren

Geef twee sealed waarden door en schakel op hun combinatie — gebruik een when met voorwaarden.

sealed class Theme { object Light : Theme(); object Dark : Theme() }
sealed class Lang { object En : Lang(); object Tr : Lang() }
fun greet(theme: Theme, lang: Lang) = when {
    theme is Theme.Dark && lang is Lang.Tr -> "Karanlik Merhaba"
    theme is Theme.Light && lang is Lang.Tr -> "Aydinlik Merhaba"
    theme is Theme.Dark -> "Dark Hello"
    theme is Theme.Light -> "Light Hello"
    else -> "?"
}
fun main() {
    println(greet(Theme.Dark, Lang.Tr))
}

Statusmachine met geneste varianten

Modelleer werkstromen met meerdere stappen als geneste sealed typen — elke stap heeft zijn eigen varianten.

sealed class Checkout {
    object Start : Checkout()
    sealed class Payment : Checkout() {
        object Pending : Payment()
        data class Failed(val reason: String) : Payment()
        object Captured : Payment()
    }
    object Shipped : Checkout()
    object Delivered : Checkout()
}
fun describe(c: Checkout) = when (c) {
    Checkout.Start -> "starting"
    Checkout.Payment.Pending -> "awaiting payment"
    is Checkout.Payment.Failed -> "payment failed: ${c.reason}"
    Checkout.Payment.Captured -> "paid"
    Checkout.Shipped -> "shipped"
    Checkout.Delivered -> "delivered"
}
fun main() {
    println(describe(Checkout.Payment.Failed("card declined")))
}

Sealed hiërarchieën hergebruiken tussen modules

Sealed typen kun je het beste per module definiëren. Bied voor compositie tussen modules een sealed interface aan, zodat elke module zijn eigen implementaties kan toevoegen.

sealed interface Notification
data class Email(val to: String) : Notification
data class Sms(val phone: String) : Notification
fun send(n: Notification) = when (n) {
    is Email -> "sending email to ${n.to}"
    is Sms -> "texting ${n.phone}"
}
fun main() {
    println(send(Email("a@example.com")))
}

Gemeenschappelijke basiseigenschappen

Sealed klassen kunnen gemeenschappelijke eigenschappen definiëren — alle subtypen erven ze. Zo blijven status en metagegevens DRY.

sealed class HttpResponse(val code: Int) {
    class Ok(val body: String) : HttpResponse(200)
    class NotFound(val path: String) : HttpResponse(404)
    class ServerError(val cause: String) : HttpResponse(500)
}
fun describe(r: HttpResponse) = "[${r.code}] " + when (r) {
    is HttpResponse.Ok -> r.body
    is HttpResponse.NotFound -> "not found: ${r.path}"
    is HttpResponse.ServerError -> "fail: ${r.cause}"
}
fun main() {
    println(describe(HttpResponse.Ok("hello")))
}

Recursieve bomen modelleren

Sealed typen beschrijven recursieve structuren, zoals expressiebomen, op natuurlijke wijze.

sealed class Expr {
    data class Num(val value: Int) : Expr()
    data class Add(val left: Expr, val right: Expr) : Expr()
    data class Mul(val left: Expr, val right: Expr) : Expr()
}
fun eval(e: Expr): Int = when (e) {
    is Expr.Num -> e.value
    is Expr.Add -> eval(e.left) + eval(e.right)
    is Expr.Mul -> eval(e.left) * eval(e.right)
}
fun main() {
    val expr = Expr.Add(Expr.Num(3), Expr.Mul(Expr.Num(4), Expr.Num(5)))
    println(eval(expr)) // 23
}

Combineren met generieken

Sealed typen kunnen generiek zijn, waardoor getypeerde resultaatomhulsels zoals Result<T> mogelijk worden.

sealed class ApiResult<out T> {
    data class Success<T>(val data: T) : ApiResult<T>()
    data class Failure(val message: String) : ApiResult<Nothing>()
}
fun handle(r: ApiResult<String>) = when (r) {
    is ApiResult.Success -> "got ${r.data}"
    is ApiResult.Failure -> "err: ${r.message}"
}
fun main() {
    println(handle(ApiResult.Success("hi")))
    println(handle(ApiResult.Failure("nope")))
}

Antipatroon: te diep nesten

Diep nesten verbergt de bedoeling. Als een sealed boom meer dan twee niveaus diep is, overweeg dan om hem af te vlakken of deelbomen naar hun eigen bestanden te verplaatsen.

sealed class Top {
    sealed class Mid : Top() {
        sealed class Deep : Mid() {
            object Leaf : Deep()
        }
    }
}
fun main() {
    val l = Top.Mid.Deep.Leaf
    println(l::class.simpleName)
}

Combineren via compositie

Wanneer twee statusdimensies onafhankelijk zijn, geef dan de voorkeur aan compositie (een data klasse die twee sealed waarden omhult) boven diep geneste hiërarchieën.

sealed class Loading { object Active : Loading(); object Idle : Loading() }
sealed class Auth { data class Signed(val id: Int) : Auth(); object Anon : Auth() }
data class AppState(val loading: Loading, val auth: Auth)
fun main() {
    val s = AppState(Loading.Active, Auth.Signed(1))
    println(s)
}

Korte controle

Wat is de aanbevolen aanpak wanneer twee statusdimensies onafhankelijk zijn?

Samenvatting

Nest sealed typen voor status in boomvorm; combineer onafhankelijke sealed hiërarchieën met compositie (een omhullende data klasse). Voeg gemeenschappelijke eigenschappen toe aan een sealed basis, gebruik generieken voor getypeerde resultaten en modelleer recursieve structuren op natuurlijke wijze. Houd het nesten ondiep.

Gratis beginnen

Leer Kotlin met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
51
Lessen
203

Veelgestelde vragen

Is de les “Sealed hiërarchieën nesten en combineren” gratis?

Ja — je kunt hier op het web alle 3 lessen van het leerpad Kotlin Academy, waaronder “Sealed hiërarchieën nesten en combineren”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus Kotlin Academy bevat in totaal 4 lessen.

Wat leer ik in “Sealed hiërarchieën nesten en combineren”?

Bouw complexe state machines door sealed typen te nesten. Je oefent met Kotlin Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Kotlin Academy te beginnen?

Ervaring vooraf is niet nodig. Kotlin Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.

Hoe lang duurt de les “Sealed hiërarchieën nesten en combineren”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Kotlin Academy?

Ja. Elke les over Kotlin Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. sealed class versus sealed interface: wanneer gebruikt u welke?
  2. Exhaustive when met sealed hiërarchieën
  3. UI-status modelleren met sealed classes
  4. Sealed hiërarchieën nesten en combineren
← Terug naar Kotlin Academy