Classes scellées à Kotlin

Cours scellés à Kotlin

1. introduction

En termes simples, le langage Kotlin a emprunté un certain nombre de concepts à d’autres langages fonctionnels pour aider à écrire un code plus sûr et lisible. Les hiérarchies scellées est l'un de ces concepts.

2. Qu'est-ce qu'une classe scellée?

Les classes scellées nous permettent de corriger les hiérarchies de types et interdisent aux développeurs de créer de nouvelles sous-classes.

Ils sont utiles lorsque vous avez une hiérarchie d'héritage très stricte, avec un ensemble spécifique de sous-classes possibles et aucune autre. The compiler guarantees that only classes defined in the same source file as the sealed class are able to inherit from it.

Les classes scellées sont également implicitementabstract. Ils doivent être traités comme tels dans le reste de votre code, sauf que rien d'autre ne peut les implémenter.

Les classes scellées peuvent avoir des champs et des méthodes définis, y compris des fonctions abstraites et implémentées. Cela signifie que vous pouvez avoir une représentation de base de la classe, puis l’ajuster en fonction des sous-classes.

3. Quand utiliser les classes scellées?

Sealed classes are designed to be used when there are a very specific set of possible options pour une valeur, et où chacune de ces options est fonctionnellement différente - justeAlgebraic Data Types.

Les cas d'utilisation courants peuvent inclure l'implémentation d'unState Machine ou d'unMonadic Programming, qui devient de plus en plus populaire avec l'avènement des concepts de programmation fonctionnelle.

Chaque fois que vous avez plusieurs options et qu'elles ne diffèrent que par la signification des données, vous feriez peut-être mieux d'utiliserEnum Classes à la place.

Chaque fois que vous avez un nombre d'options inconnu, vous ne pouvez pas utiliser une classe scellée, car cela vous empêchera d'ajouter des options en dehors du fichier source d'origine.

4. Écrire des classes scellées

Commençons par écrire notre propre classe scellée - le bon exemple d'une telle hiérarchie scellée est unOptional de Java 8 - qui peut êtreSome ouNone.

Lors de la mise en œuvre, il est judicieux de limiter la possibilité de créer de nouvelles implémentations - les deux implémentations fournies sont exhaustives et personne ne devrait ajouter la leur.

En tant que tel, nous pouvons implémenter ceci:

sealed class Optional {
    // ...
    abstract fun isPresent(): Boolean
}

data class Some(val value: V) : Optional() {
    // ...
    override fun isPresent(): Boolean = true
}

class None : Optional() {
    // ...
    override fun isPresent(): Boolean = false
}

Il peut maintenant être garanti que chaque fois que vous avez une instance deOptional<V>, vous avez en fait unSome<V> ou un None<V>.

Dans Java 8, l'implémentation réelle est différente en raison de l'absence de classes scellées.

Nous pouvons ensuite en faire usage dans nos calculs:

val result: Optional = divide(1, 0)
println(result.isPresent())
if (result is Some) {
    println(result.value)
}

La première ligne renverra unSome ou unNone. Nous publions ensuite si nous avons ou non un résultat.

5. Utiliser avec When

Kotlin prend en charge l'utilisation de classes scellées dans ses constructionswhen. Parce qu'il y a toujours un ensemble exact de sous-classes possibles,the compiler is able to warn you if any branch is not handled, in exactly the same way that it does for enumerations.

Cela signifie que dans de telles situations, il n'y a normalement pas besoin d'un gestionnaire fourre-tout, ce qui signifie que l'ajout d'une nouvelle sous-classe est automatiquement sûr - le compilateur vous avertira immédiatement si vous ne l'avez pas géré, et vous aurez besoin pour corriger ces erreurs avant de continuer.

L'exemple ci-dessus peut être étendu pour afficher le résultat ou une erreur en fonction du type renvoyé:

val message = when (result) {
    is Some -> "Answer: ${result.value}"
    is None -> "No result"
}
println(message)

Si l'une des deux branches manquait, cela ne compilerait pas et entraînerait une erreur de:

'when' expression must be exhaustive, add necessary 'else' branch

6. Sommaire

Les classes scellées peuvent être un outil précieux pour votre boîte à outils de conception d'API. Autoriser une hiérarchie de classes structurée bien connue qui ne peut jamais être l’une des séries de classes attendues peut permettre de supprimer de votre code tout un ensemble de conditions d’erreur potentielles, tout en simplifiant la lecture et la maintenance.

Comme toujours, des extraits de code peuvent être trouvésover on GitHub.