ProgrammationDéveloppeur Android

Comment fonctionne l'héritage des constantes et des objets en Kotlin ? Quels sont les pièges de l'implémentation des propriétés immuables (const val et val) lors de l'héritage et de la compilation ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

En Kotlin, le modificateur const val est utilisé uniquement pour les constantes de compilation au niveau top-level (au niveau du fichier), ou à l'intérieur des objets (object) et des objets compagnons. Les propriétés déclarées comme val à l'intérieur des classes deviennent des propriétés finales normales sans initialisation statique. Une particularité importante : const val ne peut pas être hérité, alors que val peut être redéfini (si autorisé).

Les constantes (const val) ne peuvent pas être abstraites, car elles doivent avoir une valeur au moment de la compilation. Les val normaux permettent de réaliser un modèle de constantes dans les hiérarchies via des propriétés ouvertes, cependant, à l'exécution, elles seront accessibles via un getter, ce qui diffère de la compilation en Java.

Exemple:

open class Base { open val info: String = "base" } class Child : Base() { override val info = "child" } object Constants { const val APPLICATION_NAME = "MyApp" }

Question piège.

Peut-on déclarer const val dans une interface ou une classe abstraite et ensuite le redéfinir/hériter ?

Réponse avec exemple:

Non. En Kotlin, il n'est pas possible de déclarer const val à l'intérieur d'une interface ou d'une classe abstraite — cela est autorisé uniquement au niveau des objets (object) et top-level. Il n'existe pas de variables équivalentes de type static final disponibles pour l'héritage.

interface Foo { // const val X = "constant" // erreur de compilation : les 'const val' ne sont autorisées qu'au niveau top-level, dans des objets, ou dans des objets compagnons }

Exemples d'erreurs réelles dues à une méconnaissance des subtilités du sujet.


Histoire

L'équipe a tenté de réutiliser des constantes de chaîne via l'héritage d'interface dans plusieurs modules Android, en les déclarant comme const val — ils ont obtenu une erreur de compilation et ont été contraints de déplacer les constantes au niveau top-level, ce qui a détérioré l'encapsulation.


Histoire

Dans un projet, ils ont transféré tous les champs Java static final dans des champs Kotlin val dans des classes ouvertes, en s'attendant à un comportement similaire (constante de compilation), mais ils sont devenus des propriétés normales avec getter. En conséquence, le temps d'accès a augmenté, ce qui a eu un impact négatif sur les chemins chauds (hot path) de l'application microservices.


Histoire

Lors de la migration des classes Java de conteneurs de constantes vers Kotlin, les développeurs ont créé des constantes à l'intérieur de l'objet compagnon, mais ont rencontré des problèmes d'accès depuis le code Java : les constantes étaient visibles comme des champs du compagnon lui-même, et non de la classe, ce qui a provoqué de la confusion dans l'API et des bugs supplémentaires d'interopérabilité.