Sobes.tech
Middle

Parlez des classes imbriquées et dans quels cas elles sont utilisées.

sobes.tech IA

Réponse de l'IA

Les classes imbriquées (Nested Classes) en Java sont des classes définies à l’intérieur d’une autre classe. Elles se divisent en deux types : statiques (Static Nested Classes) et internes (Inner Classes).

Classes imbriquées statiques

  • Déclarées avec le modificateur static.
  • N’ont accès qu’aux membres statiques de la classe externe (même ceux cachés).
  • N’ont pas accès aux membres non statiques de la classe externe.
  • Pour créer une instance d’une classe imbriquée statique, aucune instance de la classe externe n’est requise :
    // Classe externe
    class Outer {
        static int outerStaticField;
        int outerInstanceField;
    
        // Classe imbriquée statique
        static class StaticNested {
            void accessOuter() {
                // Accès au champ statique de la classe externe
                System.out.println(Outer.outerStaticField);
                // Pas d’accès à outerInstanceField
                // System.out.println(outerInstanceField); // Erreur de compilation
            }
        }
    }
    
    // Utilisation de la classe imbriquée statique
    class Main {
        public static void main(String[] args) {
            Outer.StaticNested nestedObject = new Outer.StaticNested();
            nestedObject.accessOuter();
        }
    }
    

Classes internes

  • Ne sont pas déclarées avec le modificateur static.
  • Ont un accès complet à tous les membres de la classe externe (statiques et non statiques, même ceux cachés).
  • Une instance de la classe interne ne peut exister sans une instance de la classe externe.
  • Pour créer une instance de la classe interne, une instance de la classe externe est requise :
    // Classe externe
    class Outer {
        static int outerStaticField;
        int outerInstanceField;
    
        // Classe interne
        class Inner {
            void accessOuter() {
                // Accès au champ statique de la classe externe
                System.out.println(Outer.outerStaticField);
                // Accès au champ non statique de la classe externe
                System.out.println(outerInstanceField);
            }
        }
    }
    
    // Utilisation de la classe interne
    class Main {
        public static void main(String[] args) {
            Outer outerObject = new Outer();
            Outer.Inner innerObject = outerObject.new Inner();
            innerObject.accessOuter();
        }
    }
    

Les classes internes se subdivisent en :

  • Classes internes régulières : Définies directement à l’intérieur du corps de la classe externe.
  • Classes internes locales : Définies à l’intérieur de méthodes, constructeurs ou blocs d’initialisation. Ne sont visibles qu’à l’intérieur de ce bloc.
    class Outer {
        void display() {
            class LocalInner { // Classe interne locale
                void message() {
                    System.out.println("Classe interne locale");
                }
            }
            LocalInner obj = new LocalInner();
            obj.message();
        }
    }
    
  • Classes internes anonymes : Classes sans nom, utilisées pour créer une instance d’une classe ou interface et fournir leur implémentation immédiatement. Souvent utilisées avec des écouteurs d’événements.
    interface Greeting {
        void sayHello();
    }
    
    class Main {
        public static void main(String[] args) {
            Greeting greeting = new Greeting() { // Classe interne anonyme
                @Override
                public void sayHello() {
                    System.out.println("Bonjour!");
                }
            };
            greeting.sayHello();
        }
    }
    

Quand appliquer les classes imbriquées :

  • Regroupement logique : Si une classe fait partie uniquement d’une autre classe et a du sens de les regrouper. Cela améliore la lisibilité et la maintenabilité du code.
  • Encapsulation : Les classes imbriquées peuvent accéder aux membres de la classe externe, ce qui assure une relation plus étroite et la possibilité de cacher les détails d’implémentation.
  • Code plus lisible : Lorsqu’une petite classe simple n’est utilisée qu’à un seul endroit, l’imbriquer peut rendre le code plus propre.
  • Utilisation efficace des ressources : Les classes internes ont accès aux membres de la classe externe sans besoin de les transmettre explicitement, ce qui peut simplifier le code. Un exemple est la mise en œuvre d’itérateurs.
  • Implémentation d’interfaces ou extension de classes dans un contexte : Les classes internes anonymes sont souvent utilisées pour fournir une implémentation compacte d’interfaces ou de classes abstraites "à la volée".
  • Cacher l’implémentation : Cacher une classe à l’intérieur d’une autre, la rendant invisible de l’extérieur.

Comparaison entre classes imbriquées statiques et internes :

Paramètre Classe imbriquée statique Classe interne
Modificateur static Oui Non
Accès aux membres de la classe externe Seulement statiques (même privés) Tous les membres (statiques et non statiques, privés)
Nécessite une instance de la classe externe pour créer Non Oui
Relation avec l’instance de la classe externe Non Oui

Le choix entre une classe imbriquée statique et une interne dépend de si la classe interne a besoin d’accéder aux membres non statiques de la classe externe. Si oui, utilisez la classe interne. Sinon, la classe imbriquée statique est un choix plus approprié, car elle n’est pas liée à une instance de la classe externe et peut être plus efficace.