ProgrammationDéveloppeur Backend

Décrivez les caractéristiques de la déclaration et de l'utilisation des classes imbriquées (nested) et internes (inner) en Kotlin. Quand doivent-elles être appliquées, quelle est leur différence par rapport aux classes imbriquées en Java, et quels pièges existent ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Les classes imbriquées (nested) et internes (inner) en Kotlin sont utilisées pour le groupement logique et l'encapsulation de fonctionnalités à l'intérieur d'une classe externe.

Contexte

L'idée des classes imbriquées provient de Java comme un moyen de structurer le code et d'isoler des composants auxiliaires à l'intérieur de la classe principale. En Kotlin, la syntaxe et l'approche sont héritées de Java, mais avec des différences importantes.

Problème

Le principal défi est de bien séparer les classes auxiliaires là où elles ne devraient pas exister en dehors du contexte de la classe externe, tout en nécessitant différents niveaux d'accès aux membres de la classe externe. En Java, par défaut, une classe imbriquée est une classe interne, tandis qu'en Kotlin, par défaut, elle est imbriquée (statique).

Solution

En Kotlin, par défaut, la déclaration d'une classe à l'intérieur d'une autre crée une classe statique (nested), c'est-à-dire que cette classe n'a pas accès aux membres de la classe externe. Pour obtenir l'accès, on utilise le mot-clé inner.

Exemple de code:

class Outer { private val secret = "outside" class Nested { fun call() = "nested: no access to Outer.secret" } inner class Inner { fun call() = "inner: can access $secret" } }

Caractéristiques clés :

  • La classe imbriquée (class Nested) n'a par défaut pas de référence à l'instance de la classe externe ;
  • La classe interne (inner class Inner) a une référence et peut accéder aux membres de la classe externe, même aux privés ;
  • L'initialisation de la classe interne nécessite une instance de la classe externe.

Questions pièges.

Une classe imbriquée (nested) peut-elle accéder à une propriété privée de la classe externe ?

Non, la classe imbriquée (par défaut) en Kotlin est statique et ne contient pas de référence à la classe externe, donc elle n'a pas accès à ses propriétés et méthodes.

Quelle est la différence entre les classes internes en Kotlin et en Java ?

En Java, une classe imbriquée par défaut n'est pas statique et a une référence à l'externe. En Kotlin, au contraire ; une classe imbriquée est statique, seule la classe interne reçoit une référence à l'instance externe.

Peut-on déclarer une classe interne dans un objet (object) ?

Non, une classe interne (inner) ne peut pas être déclarée à l'intérieur d'un objet, car l'objet ne peut pas être instancié.

Erreurs typiques et anti-patterns

  • Déclaration d'une classe interne (inner) là où l'accès à la classe externe n'est pas requis — couplage excessif ;
  • L'accès aux membres de la classe externe depuis la classe imbriquée provoque une erreur de compilation ;
  • Création de fuites de mémoire à cause des références cachées à la classe externe via inner.

Exemple de la vie quotidienne

Cas négatif

Un développeur déclare une classe interne, qui n'utilise pas les propriétés de la classe externe :

class Container { inner class Helper { fun help() = "help" } }

Avantages :

La classe est facilement accessible depuis l'objet externe.

Inconvénients :

  • Couplage excessif.
  • Éventuelles fuites à cause de la référence cachée à Container.

Cas positif

Utilisation d'une classe interne pour implémenter l'accès à l'état privé de la classe externe :

class Auth { private var token: String = "" inner class TokenManager { fun updateToken(new: String) { token = new } } }

Avantages :

  • Contrôle total de l'accès aux propriétés privées ;
  • Protection de l'encapsulation.

Inconvénients :

  • Complique la testabilité ;
  • À éviter si possible sans liaison à la classe externe.