Les “sealed class” en Kotlin

Les sealed class en Kotlin

Les classes scellées (ou “sealed class” en anglais) sont un concept de programmation disponible dans le langage de programmation Kotlin. Elles permettent de définir des classes qui ne peuvent être étendues (ou sous-classées) que dans le même fichier de source.
Cela peut être utile pour créer des types de données qui ne peuvent prendre qu’un nombre fini de valeurs possibles.

Voici un exemple de définition d’une classe scellée en Kotlin :

sealed class Shape 
{
    class Circle(val radius: Double) : Shape()
    class Rectangle(val width: Double, val height: Double) : Shape()
    class Triangle(val base: Double, val height: Double) : Shape()
}


Dans cet exemple, la classe Shape est définie comme étant sealed. Elle ne peut être étendue que par les classes Circle, Rectangle et Triangle, qui sont définies dans le même fichier de source.

Il est important de noter que les classes filles d’une classe scellée doivent être définies comme des classes internes à la classe scellée, comme dans l’exemple ci-dessus.
Sinon, vous obtiendrez une erreur de compilation.

Pour utiliser une “sealed class”, vous pouvez utiliser un bloc when pour vérifier les différentes instances possibles :

fun calculateArea(shape: Shape): Double 
{
    return when (shape) {
        is Shape.Circle -> Math.PI * shape.radius * shape.radius
        is Shape.Rectangle -> shape.width * shape.height
        is Shape.Triangle -> shape.base * shape.height / 2
    }
}


Dans cet exemple, le bloc when vérifie si l’instance de shape est une instance de Shape.Circle, Shape.Rectangle ou Shape.Triangle, et renvoie la surface appropriée en conséquence.

Il est important de noter que, contrairement aux classes ordinaires, il n’est pas nécessaire de fournir un cas “par défaut” dans un bloc when qui utilise une classe scellée, car le compilateur peut garantir qu’il existe une correspondance pour toutes les valeurs possibles.

En résumé, les sealed class en Kotlin permettent de définir des classes qui ne peuvent être étendues (ou sous-classées) que dans le même fichier de source, et sont utiles pour créer des types de données qui ne peuvent prendre qu’un nombre fini de valeurs possibles.
Pour utiliser une classe scellée, vous pouvez utiliser un bloc when pour vérifier les différentes instances possibles.

Il est important de noter que les classes filles d’une classe scellée doivent être définies comme des classes internes à la classe scellée, et qu’il n’est pas nécessaire de fournir un cas “par défaut”, car le compilateur peut garantir qu’il existe une correspondance pour toutes les valeurs possibles.

Voici un exemple d’utilisation d’une classe scellée pour représenter les états d’une application :

sealed class AppState 
{
    object Loading : AppState()
    object Authenticated : AppState()
    object Unauthenticated : AppState()
    data class Error(val message: String) : AppState()
}


Dans cet exemple, la classe AppState représente les différents états que l’application peut prendre: Loading, Authenticated, Unauthenticated et Error.
Chacun de ces états est une classe interne à AppState qui étend la classe scellée.

On peut maintenant utiliser un bloc when pour gérer les différents états de l’application de la manière suivante :

fun handleAppState(state: AppState) 
{
    when(state) 
    {
        is AppState.Loading -> showLoading()
        is AppState.Authenticated -> showAuthenticated()
        is AppState.Unauthenticated -> showUnauthenticated()
        is AppState.Error -> showError(state.message)
    }
}


En utilisant des sealed class, vous pouvez vous assurer que tous les états possibles de votre application sont explicitement définis et gérés, ce qui peut aider à éviter les bugs liés à des états non gérés ou non prévus.

Il y a encore d’autres aspects importants à couvrir lorsqu’il s’agit de classes scellées en Kotlin.

  • Il est possible de définir des propriétés et des méthodes sur les classes scellées, qui seront héritées par les classes filles.
  • Il est également possible de fournir un constructeur aux classes scellées, qui sera appelé par les constructeurs des classes filles.
  • Il est possible de définir des classes scellées à l’intérieur d’autres classes, pour créer des hiérarchies de classes scellées plus complexes.
  • Il est possible de créer une classe scellée sans aucune classe fille, mais cela n’a généralement pas de sens, car une telle classe ne pourra jamais être instanciée.

Voici un exemple d’une classe scellée avec propriété, méthode et constructeur :

sealed class Shape(val color: String) 
{
    class Circle(radius: Double, color: String) : Shape(color) 
    {
        val radius: Double = radius
        fun area() = Math.PI * radius * radius
    }
    
    class Rectangle(val width: Double, val height: Double, color: String) : Shape(color) 
    {
        fun area() = width * height
    }
    
    class Triangle(val base: Double, val height: Double, color: String) : Shape(color) 
    {
        fun area() = base * height / 2
    }
}


En utilisant les sealed class, vous pouvez créer des types de données plus robustes et fiables en restreignant les valeurs possibles et en garantissant que tous les cas possibles sont explicitement gérés.

1 réflexion sur “Les “sealed class” en Kotlin”

  1. J’ai appris récemment que ce concepte existait également en Go.
    C’est une manière d’implémenté le type somme de plusieurs types. Un concepts que l’on retrouve beaucoup dans les langages fonctionnels.

    Wikipédia m’a bien aidé sur la compréhension du sujet: https://fr.wikipedia.org/wiki/Type_alg%C3%A9brique_de_donn%C3%A9es#Type_somme
    Une discution à ce sujet en Go (désolé j’aimerais avoir l’équivalent en Kotlin): https://zestedesavoir.com/forums/sujet/16769/interface-non-exportee/

    Par-contre, je pensais que Kotlin était fonctionnel ? Un code comme celui-ci ne m’aurait pas étonné plutôt que des interfaces scellées.

    “`
    type SumType =
    | New of Id: int
    | Cancel of Id: int
    “`

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Retour en haut
%d blogueurs aiment cette page :