0Pricing
Kotlin Academy · Leçon

Imbriquer et combiner des hiérarchies scellées

Construisez des machines à états complexes en imbriquant des types scellés.

Imbriquer et combiner des hiérarchies scellées est une leçon Kotlin Academy gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Kotlin Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Kotlin Academy comprend 4 leçons au total.

Composer des arbres d'états

Dans les applications réelles, un état comporte souvent plusieurs dimensions. Imbriquez des types scellés ou combinez des hiérarchies distinctes pour modéliser proprement les domaines complexes.

Classe scellée imbriquée

Déclarez des types scellés enfants à l'intérieur d'un type scellé parent. Le compilateur impose toujours l'exhaustivité dans l'ensemble de l'arbre.

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"))))
}

Interfaces scellées pour les fonctionnalités combinables

Utilisez des interfaces scellées lorsqu'un état possède plusieurs aspects indépendants : chaque aspect correspond à une interface différente.

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))
}

Combiner des hiérarchies

Transmettez deux valeurs scellées et sélectionnez leur combinaison : utilisez une expression when avec garde.

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))
}

Machine à états avec variantes imbriquées

Modélisez les processus en plusieurs étapes avec des types scellés imbriqués : chaque étape possède ses propres variantes.

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")))
}

Réutiliser des hiérarchies scellées entre modules

Il est préférable de définir les types scellés par module. Pour les combiner entre modules, exposez une interface scellée afin que chaque module puisse ajouter ses propres implémentations.

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")))
}

Propriétés de base communes

Les classes scellées peuvent déclarer des propriétés communes : tous les sous-types en héritent. Cela conserve l'état et les métadonnées 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")))
}

Modéliser des arbres récursifs

Les types scellés décrivent naturellement des structures récursives telles que les arbres d'expressions.

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
}

Combiner avec les types génériques

Les types scellés peuvent être génériques, ce qui permet de créer des enveloppes de résultats typées comme Result<T>.

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")))
}

Anti-modèle&nbsp;: imbrication excessive

Une imbrication profonde masque l'intention. Si un arbre scellé comporte plus de deux niveaux, envisagez de l'aplatir ou d'extraire les sous-arbres dans leurs propres fichiers.

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)
}

Combiner par composition

Lorsque deux dimensions d'état sont indépendantes, préférez la composition (une classe de données qui enveloppe deux valeurs scellées) aux hiérarchies profondément imbriquées.

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)
}

Vérification rapide

Quelle approche est recommandée lorsque deux dimensions d'état sont indépendantes ?

Récapitulatif

Imbriquez les types scellés pour représenter un état arborescent : combinez les hiérarchies scellées indépendantes par composition (avec une classe de données enveloppante). Ajoutez les propriétés communes à une classe de base scellée, utilisez les types génériques pour les résultats typés et modélisez naturellement les structures récursives. Gardez l'imbrication peu profonde.

Questions Fréquemment Posées

La leçon « Imbriquer et combiner des hiérarchies scellées » est-elle gratuite ?

Oui — le texte complet de « Imbriquer et combiner des hiérarchies scellées » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Kotlin Academy, passe à CoddyKit PRO. Le cours Kotlin Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Imbriquer et combiner des hiérarchies scellées » ?

Construisez des machines à états complexes en imbriquant des types scellés. Tu pratiques Kotlin Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Kotlin Academy ?

Aucune expérience préalable n'est requise. Kotlin Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.

Combien de temps prend la leçon « Imbriquer et combiner des hiérarchies scellées » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Kotlin Academy ?

Oui. Chaque leçon Kotlin Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. sealed class ou sealed interface : quand utiliser chacune
  2. when exhaustif avec des hiérarchies scellées
  3. Modéliser l’état de l’interface utilisateur avec des classes scellées
  4. Imbriquer et combiner des hiérarchies scellées
← Retour à Kotlin Academy