Cours en ligne à Kotlin

1. Vue d'ensemble

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

2. Configuration

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 un avertissement indiquant le statut expérimental de la fonctionnalité.

Pour éviter cet avertissement, nous pouvons ajouter l'option de compilateur Maven suivante à 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 par lui-même.

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

Voyons un exemple d'une classe en ligne appelée InlinedCircleRadius avec une propriété de type Double représentant le rayon:

val circleRadius = InlinedCircleRadius(5.5)

Pour la JVM, notre code est en fait juste:

val circleRadius = 5.5

Notez que notre InlinedCircleRadius n'est pas instancié dans le code compilé car la valeur sous-jacente est incorporée, ce qui nous évite les 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.

Une seule propriété initialisée dans le constructeur principal est la condition de base d'une classe en ligne . La propriété unique représentera l'instance de classe au moment de l'exécution.

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

inline class InlineDoubleWrapper(val doubleValue : Double)

Nous avons défini InlineDoubleWrapper comme un simple wrapper sur un objet Double et lui avons appliqué le mot clé en ligne . 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 du groupe

Jusqu'à présent, nous utilisions des classes en ligne comme de simples wrappers. Mais ils sont bien plus que cela. Ils nous permettent également de définir des propriétés et des fonctions comme les classes régulières. 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é diamètreOfCircle . Il instanciera notre classe en ligne CircleRadius , 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 fonction areaOfCircle :

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

Cependant, il y a quelques limitations sur ce que nous pouvons et ne pouvons pas définir dans nos classes en ligne. Bien que les propriétés et les fonctions soient autorisées, nous devons mentionner que les blocs init , les classes internes et les champs de sauvegarde ne le sont pas.

5. Héritage

Il est important de mentionner que les classes en ligne ne peuvent hériter que des interfaces , et comme nous ne pouvons pas avoir de sous-classes, les classes en ligne sont également effectivement finales.

Étant donné une interface Drawable avec une méthode draw () , nous implémenterons cette méthode dans notre classe CircleRadius :

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 dans 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 de code peuvent être trouvés sur GitHub.