ProgrammationDéveloppeur Android

Qu'est-ce que les propriétés d'extension en Kotlin, comment sont-elles réalisées, quelles sont les limitations par rapport aux propriétés ordinaires ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Les propriétés d'extension sont des extensions pour des classes qui permettent d'ajouter des accesseurs et des mutateurs sans possibilité d'ajouter un état (backing field). En Java, cette possibilité n'existe pas, et l'analogue est l'écriture de méthodes utilitaires. Historiquement, pour ajouter des fonctionnalités, il a fallu utiliser des méthodes statiques ou des objets Wrapper.

Problème : dans les classes tierces, il manque souvent les propriétés nécessaires. On veut étendre la classe de manière concise et sécurisée, sans enfreindre l'encapsulation.

Solution : en Kotlin, on peut déclarer une propriété d'extension, qui ressemble à une propriété ordinaire, mais est réalisée sous forme de fonctions. Cela permet d'étendre des types pour lesquels nous n'avons pas accès au code source, de manière pratique.

Exemple de code :

val String.firstChar: Char get() = this[0] println("Kotlin".firstChar) // K

Caractéristiques clés :

  • La propriété d'extension est un sucre syntaxique, ne peut pas avoir d'état (on ne peut pas déclarer de backing field).
  • Les propriétés set ne sont réalisées que par une fonction.
  • Elles ne fonctionnent qu'avec l'API publique de la classe et ne peuvent pas accéder aux membres privés.

Questions pièges.

Peut-on ajouter un backing field (état) dans une propriété d'extension ?

Non, une propriété d'extension ne fait que calculer la valeur à la volée et ne peut pas stocker d'état.

Les propriétés d'extension peuvent-elles redéfinir des propriétés dans des classes héritées ?

Non, les propriétés d'extension (comme les fonctions d'extension) sont intrinsèquement statiques : elles ne peuvent pas être redéfinies ou être virtuelles.

Comment une propriété d'extension est-elle compilée, et pourquoi n'est-elle pas un analogue syntaxique d'une propriété ordinaire ?

Une propriété d'extension est en réalité compilée en un accesseur (et/ou mutateur) statique. Elles ne font pas partie des entités de la classe et ne sont visibles que dans le contexte du fichier où elles sont déclarées.

Erreurs typiques et anti-patterns

  • S'attendre à accéder aux membres privés de la classe à l'intérieur d'une propriété d'extension
  • Essayer de réaliser le stockage d'état via une propriété d'extension
  • Abuser des propriétés d'extension au lieu des propriétés ordinaires, quand ce n'est pas nécessaire

Exemple de la vie réelle

Cas négatif

Un développeur a essayé d'ajouter une propriété d'extension pour stocker l'état "visité" dans les View standard d'Android :

var View.isVisited: Boolean get() = ... set(value) { ... } // Erreur : pas de stockage

Avantages :

  • La syntaxe est concise

Inconvénients :

  • Attente d'une fonctionnalité impossible (impossible de stocker l'état)
  • Erreurs à l'exécution

Cas positif

Une propriété d'extension a été réalisée pour String afin d'obtenir un format étendu :

val String.asTitle: String get() = this.replaceFirstChar { it.uppercase() }

Avantages :

  • Commodité d'ajout de fonctionnalités
  • Absence d'utilitaires externes
  • Maintenance facile

Inconvénients :

  • Pas de stockage d'état (si cela est nécessaire, un autre modèle est requis)