Dans les premières versions de Kotlin, des classes sealed étaient utilisées pour restreindre la hiérarchie des types, permettant aux développeurs de contrôler explicitement les sous-types autorisés en limitant la déclaration des héritiers à un seul fichier. Pour certaines tâches, cela n'était pas suffisant, surtout lorsqu'il fallait décrire des hiérarchies similaires avec des interfaces. Pour résoudre ce problème, à partir de Kotlin 1.5, le modificateur sealed a été introduit pour les interfaces.
Les interfaces ordinaires peuvent être implémentées n'importe où dans le projet, ce qui rend souvent difficile d'assurer une clôture absolue de la hiérarchie des types et d'utiliser des vérifications de types exhaustives (exhaustive when). Cela peut entraîner des erreurs à l'exécution, rendant impossible une vérification statique de tous les cas.
Les interfaces sealed permettent de limiter la liste des classes d'implémentation dans un seul fichier, augmentant la prévisibilité du système de types et la sécurité de l'appariement des modèles (pattern matching).
sealed interface NetworkResult class Success(val data: String): NetworkResult class Failure(val error: Throwable): NetworkResult fun handle(result: NetworkResult) = when(result) { is Success -> println("Data: ${result.data}") is Failure -> println("Error: ${result.error}") // Tous les cas sont pris en compte, 'else' n'est pas nécessaire }
Caractéristiques clés :
Peut-on ajouter une sealed interface dans un fichier séparé ou l'implémenter en dehors du fichier d'origine ?
Non. Tous les types qui implémentent directement une sealed interface doivent être déclarés dans le même fichier, sinon le compilateur renverra une erreur.
Est-il permis à une sealed interface d'avoir des sous-interfaces en dehors du fichier de déclaration ?
Non. Les sous-interfaces doivent également se situer dans ce même fichier. Toute la hiérarchie est fermée à l'intérieur du fichier.
Les interfaces sealed ont-elles un impact sur la performance à l'exécution ?
Non directement, mais elles permettent d'utiliser des vérifications de types sûres à la compilation, ce qui réduit la probabilité d'erreurs à l'exécution, simplifie le code et peut indirectement accélérer les tests.
Un développeur déclare une sealed interface NetworkAction dans un fichier, mais les implémentations sont dispersées dans différentes classes et fichiers. Le problème est découvert tardivement : le compilateur signale une violation de la règle, et corriger la structure s'avère difficile, en particulier dans un projet large.
Avantages :
Inconvénients :
La sealed interface OrderResult et les classes Success/Failure sont déclarées dans un seul fichier. La vérification when est toujours exhaustive, aucune branche n'est omise.
Avantages :
Inconvénients :