Classes en ligne à Kotlin

Cours en ligne à Kotlin

1. Vue d'ensemble

Dans Kotlin 1.3+, nous avons un nouveau type expérimental de classe, appeléinline class. Dans ce didacticiel, nous nous concentrerons sur l'utilisation des classes en ligne et sur certaines de leurs limitations.

2. Installer

Comme nous l'avons mentionné précédemment, les classes en ligne sont une fonctionnalité expérimentale de Kotlin. En conséquence, le compilateur lancera unwarning indiquant le statut expérimental de la fonctionnalité.

Pour éviter cet avertissement, nous pouvons ajouter lesMaven compiler option suivants à notre configuration:


    
        -XXLanguage:+InlineClasses
    

3. Que sont les classes en ligne

Les classes en ligne nous fournissent un moyen d'encapsuler un type, ajoutant ainsi des fonctionnalités et créant un nouveau type.

Contrairement aux wrappers classiques (non intégrés), ils bénéficieront de performances améliorées. Cela se produit car les données sont intégrées dans leurs utilisations et l'instanciation d'objet est ignorée dans le code compilé obtenu.

Voyons un exemple de classe en ligne appeléeInlinedCircleRadius avec une propriété de typeDouble représentant le rayon:

val circleRadius = InlinedCircleRadius(5.5)

Pour la machine virtuelle Java, notre code est en réalité juste:

val circleRadius = 5.5

Remarquez comment notreInlinedCircleRadius n'est pas instancié dans le code compilé car la valeur sous-jacente est incorporée, ce qui nous libère des pénalités de performances associées à l'instanciation.

3.1. Exemple d'utilisation

Maintenant que nous savons ce que sont les classes en ligne, nous allons discuter de leur utilisation.

A single property initialized in the primary constructor is the basic requirement of aninline class. La propriété unique représentera l'instance de classe au moment de l'exécution.

Par conséquent, pour avoir une définition correcte, nous pouvons utiliser une seule ligne de code:

inline class InlineDoubleWrapper(val doubleValue : Double)

Nous avons définiInlineDoubleWrapper comme un simple wrapper sur un objetDouble et lui avons appliqué le mot cléinline. Enfin, nous pouvons maintenant utiliser cette classe dans notre code sans modifications supplémentaires:

@Test
fun whenInclineClassIsUsed_ThenPropertyIsReadCorrectly() {
    val piDoubleValue = InlineDoubleWrapper(3.14)
    assertEquals(3.14, piDoubleValue.doubleValue)
}

4. Membres de classe

Jusqu'à présent, nous utilisions des classes en ligne, comme de simples wrappers. Mais ils sont tellement plus que cela. They also allow us to define properties and functions just like regular classes. Cet exemple suivant définit une propriété représentant le diamètre et une fonction pour renvoyer l'aire du cercle:

inline class CircleRadius(private val circleRadius : Double) {
    val diameterOfCircle get() = 2 * circleRadius
    fun areaOfCircle = 3.14 * circleRadius * circleRadius
}

Nous allons maintenant créer un test pour notre propriétédiameterOfCircle. Il instanciera notre classe en ligneCircleRadius puis appellera la propriété:

@Test
fun givenRadius_ThenDiameterIsCorrectlyCalculated() {
    val radius = CircleRadius(5.0)
    assertEquals(10.0, radius.diameterOfCircle)
}

Et voici un test simple pour la fonctionareaOfCircle:

@Test
fun givenRadius_ThenAreaIsCorrectlyCalculated() {
    val radius = CircleRadius(5.0)
    assertEquals(78.5, radius.areaOfCircle())
}

Cependant, il existe certaines limites à ce que nous pouvons et ne pouvons pas définir dans nos classes en ligne. While properties and functions are allowed, we have to mention that init blocks, inner classes, and backing fields are not.

5. Héritage

Il est important de mentionner queinline classes can inherit only from interfaces, et comme nous ne pouvons pas avoir de sous-classes,inline classes are also effectively final.

Étant donné une interfaceDrawable avec une méthodedraw(), nous allons implémenter cette méthode dans notre classeCircleRadius:

interface Drawable {
    fun draw()
}

inline class CircleRadius(private val circleRadius : Double) : Drawable {
    val diameterOfCircle get() = 2 * circleRadius
    fun areaOfCircle() = 3.14 * circleRadius * circleRadius

    override fun draw() {
        println("Draw my circle")
    }
}

6. Conclusions

Dans cet article rapide, nous avons exploré les classes en ligne de Kotlin. De plus, nous avons parlé de l'héritage et de la définition des propriétés et des fonctions.

Comme d'habitude, tous ces exemples et extraits peuvent être trouvésover on GitHub.