Classes imbriquées en Java

Classes imbriquées en Java

1. introduction

Ce tutoriel est une introduction rapide et concise aux classes imbriquées en langage Java.

En termes simples, Java nous permet de définir des classes dans d’autres classes. Nested classes enable us to logically group classes that are only used in one place, write more readable and maintainable code and increase encapsulation.

Avant de commencer, examinons les différents types de classes imbriquées disponibles dans la langue:

  • Classes imbriquées statiques

  • Classes imbriquées non statiques

  • Cours locaux

  • Cours anonymes

Dans les sections suivantes, nous allons discuter de chacun de ces éléments en détail.

2. Classes imbriquées statiques

Voici quelques points à retenir sur les classes imbriquées statiques:

  • Comme pour les membres statiques, ceux-ci appartiennent à leur classe englobante et non à une instance de la classe.

  • Ils peuvent avoir tous les types de modificateurs d'accès dans leur déclaration

  • Ils ont uniquement accès aux membres statiques de la classe englobante

  • Ils peuvent définir des membres statiques et non statiques

Voyons comment nous pouvons déclarer une classe imbriquée statique:

public class Enclosing {

    private static int x = 1;

    public static class StaticNested {

        private void run() {
            // method implementation
        }
    }

    @Test
    public void test() {
        Enclosing.StaticNested nested = new Enclosing.StaticNested();
        nested.run();
    }
}

3. Classes imbriquées non statiques

Ensuite, voici quelques points rapides à retenir sur les classes imbriquées non statiques:

  • Ils sont aussi appelés classes intérieures

  • Ils peuvent avoir tous les types de modificateurs d'accès dans leur déclaration

  • Tout comme les variables d’instance et les méthodes, les classes internes sont associées à une instance de la classe englobante

  • Ils ont accès à tous les membres de la classe englobante, qu'ils soient statiques ou non.

  • Ils ne peuvent définir que des membres non statiques

Voici comment déclarer une classe interne:

public class Outer {

    public class Inner {
        // ...
    }
}

Si nous déclarons une classe imbriquée avec un modificateurstatic, alors c'est un membre statique. Sinon, c'est une classe interne. Même si syntaxiquement la différence n'est qu'un seul mot-clé (c'est-à-direstatic), il existe sémantiquement une énorme différence entre ces types de classes imbriquées. Les instances de classe interne sont liées aux classes de classe englobantes et ont donc accès à leurs membres. Nous devons être conscients de ce problème lorsque nous choisissons de transformer une classe imbriquée en classe interne.

Pour instancier une classe interne, nous devons d'abord instancier sa classe englobante.

Voyons comment nous pouvons y parvenir:

Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();

Dans les sous-sections suivantes, nous allons montrer quelques types spéciaux de classes internes.

3.1. Cours locaux

Les classes locales sont un type spécial de classes internes - dans lesquellesthe class is defined inside a method ou bloc de portée.

Voyons quelques points à retenir sur ce type de cours:

  • Ils ne peuvent pas avoir de modificateurs d'accès dans leur déclaration

  • Ils ont accès aux membres statiques et non statiques dans le contexte englobant

  • Ils ne peuvent définir que des membres d'instance

Voici un exemple rapide:

public class NewEnclosing {

    void run() {
        class Local {

            void run() {
                // method implementation
            }
        }
        Local local = new Local();
        local.run();
    }

    @Test
    public void test() {
        NewEnclosing newEnclosing = new NewEnclosing();
        newEnclosing.run();
    }
}

3.2. Classes Anonymes

Les classes anonymes peuvent être utilisées pour définir une implémentation d'une interface ou d'une classe abstraite sans avoir à créer une implémentation réutilisable.

Énumérons quelques points à retenir sur les classes anonymes:

  • Ils ne peuvent pas avoir de modificateurs d'accès dans leur déclaration

  • Ils ont accès aux membres statiques et non statiques dans le contexte englobant

  • Ils ne peuvent définir que des membres d'instance

  • Ce sont les seuls types de classes imbriquées qui ne peuvent pas définir de constructeurs ou étendre / implémenter d’autres classes ou interfaces

Pour définir une classe anonyme, définissons d'abord une classe abstraite simple:

abstract class SimpleAbstractClass {
    abstract void run();
}

Voyons maintenant comment nous pouvons définir une classe anonyme:

public class AnonymousInnerTest {

    @Test
    public void whenRunAnonymousClass_thenCorrect() {
        SimpleAbstractClass simpleAbstractClass = new SimpleAbstractClass() {
            void run() {
                // method implementation
            }
        };
        simpleAbstractClass.run();
    }
}

Pour plus de détails, nous pouvons trouver utile notre tutoriel surAnonymous Classes in Java.

4. Observation

The declaration of the members of an inner class shadow those of the enclosing class s'ils portent le même nom.

Dans ce cas, le mot cléthis fait référence aux instances de la classe imbriquée et les membres de la classe externe peuvent être référencés en utilisant le nom de la classe externe.

Voyons un exemple rapide:

public class NewOuter {

    int a = 1;
    static int b = 2;

    public class InnerClass {
        int a = 3;
        static final int b = 4;

        public void run() {
            System.out.println("a = " + a);
            System.out.println("b = " + b);
            System.out.println("NewOuterTest.this.a = " + NewOuter.this.a);
            System.out.println("NewOuterTest.b = " + NewOuter.b);
            System.out.println("NewOuterTest.this.b = " + NewOuter.this.b);
        }
    }

    @Test
    public void test() {
        NewOuter outer = new NewOuter();
        NewOuter.InnerClass inner = outer.new InnerClass();
        inner.run();

    }
}

5. La sérialisation

Pour éviter unjava.io.NotSerializableException lors de la tentative de sérialisation d'une classe imbriquée, nous devons:

  • Déclarez la classe imbriquée commestatic

  • Faire en sorte que la classe imbriquée et la classe englobante implémententSerializable

6. Conclusion

Dans cet article, nous avons vu ce que sont les classes imbriquées et leurs différents types. Nous avons également examiné la différence entre les types de visibilité sur le terrain et les modificateurs d'accès.

Comme toujours, l'implémentation complète de ce tutoriel peut être trouvéeover on GitHub.