ProgrammationDéveloppeur Kotlin

Qu'est-ce que les interfaces sealed (sealed interfaces) en Kotlin, comment fonctionnent-elles dans la pratique et en quoi diffèrent-elles des classes sealed ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

Historique de la question

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.

Problème

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.

Solution

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 :

  • Les interfaces sealed permettent une hiérarchie unique : seules des classes/objets du même fichier peuvent hériter
  • Les interfaces sealed peuvent être implémentées à la fois par des classes et des objets
  • Elles étendent la sécurité de type de l'expression when sans nécessiter de clause else explicite

Questions piégées.

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.

Erreurs typiques et anti-modèles

  • Déclaration de classes d'implémentation d'une sealed interface en dehors du fichier où l'interface est déclarée
  • Ajout de trop de variantes, ce qui complique la maintenance
  • Utilisation d'une sealed interface lorsque la hiérarchie des variantes peut changer (aucune clôture des variantes requise)

Exemple concret

Cas négatif

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 :

  • Permet de déclarer de nouvelles implémentations sans modifier un fichier unique

Inconvénients :

  • Enfreint les garanties de sécurité de type
  • Nécessite de refactoriser le code, ce qui est coûteux en temps

Cas positif

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 :

  • Sécurité et complétude des traitements
  • Améliore la qualité de l'architecture

Inconvénients :

  • Moins de flexibilité d'extension (toutes les modifications doivent passer par ce fichier)