La classe interne Java est définie à l’intérieur du corps d’une autre classe. La classe interne Java peut être déclarée privée, publique, protégée ou avec un accès par défaut, tandis qu’une classe externe peut avoir uniquement un accès public ou par défaut. Les classes imbriquées Java sont divisées en deux types.
-
classe imbriquée statique
Si la classe imbriquée est statique, elle est appelée classe imbriquée statique. Les classes imbriquées statiques ne peuvent accéder qu’aux membres statiques de la classe externe. Une classe imbriquée statique est identique à n’importe quelle autre classe de niveau supérieur et est imbriquée uniquement pour des raisons de commodité d’emballage. Un objet de classe statique peut être créé avec l’instruction suivante.
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
-
classe interne java
Toute classe imbriquée non statique est appelée classe interne en Java. La classe interne Java est associée à l’objet de la classe et elle peut accéder à toutes les variables et méthodes de la classe externe. Puisque les classes internes sont associées à l’instance, elles ne peuvent pas avoir de variables statiques. L’objet de la classe interne Java fait partie de l’objet de la classe externe et pour créer une instance de la classe interne, nous devons d’abord créer une instance de la classe externe. La classe interne Java peut être instanciée comme ceci;
OuterClass outerObject = new OuterClass(); OuterClass.InnerClass innerObject = outerObject.new InnerClass();
Il existe deux types spéciaux de classes internes Java.
-
classe interne locale
Si une classe est définie dans le corps d’une méthode, elle est appelée classe interne locale. Puisque la classe interne locale n’est pas associée à un objet, nous ne pouvons pas utiliser les modificateurs d’accès privé, public ou protégé avec elle. Les seuls modificateurs autorisés sont abstract ou final. Une classe interne locale peut accéder à tous les membres de la classe englobante et aux variables locales finales dans la portée où elle est définie. De plus, elle peut également accéder à une variable locale non finale de la méthode dans laquelle elle est définie, mais elle ne peut pas les modifier. Ainsi, si vous essayez d’imprimer la valeur d’une variable locale non finale, cela sera autorisé, mais si vous essayez de changer sa valeur à l’intérieur de la méthode de la classe interne locale, vous obtiendrez une erreur de compilation. Une classe interne locale peut être définie comme suit :
package com.journaldev.innerclasses; public class MainClass { private String s_main_class; public void print() { String s_print_method = ""; // classe interne locale à l'intérieur de la méthode class Logger { // peut accéder aux variables de la classe englobante String name = s_main_class; // peut accéder aux variables de méthode non finales String name1 = s_print_method; public void foo() { String name1 = s_print_method; // Le code ci-dessous générera une erreur de compilation : // La variable locale s_print_method définie dans une portée englobante doit être finale ou effectivement finale // s_print_method= ":"; } } // instancie la classe interne locale dans la méthode pour l'utiliser Logger logger = new Logger(); } }
Nous pouvons définir une classe interne locale à l’intérieur de n’importe quel bloc également, tel qu’un bloc statique, un bloc if-else, etc. Cependant, dans ce cas, la portée de la classe sera très limitée.
public class MainClass { static { class Foo { } Foo f = new Foo(); } public void bar() { if(1 < 2) { class Test { } Test t1 = new Test(); } // Ce qui suit générera une erreur en raison de la portée de la classe //Test t = new Test(); //Foo f = new Foo(); } }
-
classe interne anonyme
Une classe interne locale sans nom est connue sous le nom de classe interne anonyme. Une classe anonyme est définie et instanciée en une seule instruction. Les classes internes anonymes étendent toujours une classe ou implémentent une interface. Comme une classe anonyme n’a pas de nom, il n’est pas possible de définir un constructeur pour une classe anonyme. Les classes internes anonymes ne sont accessibles qu’au point où elles sont définies. Il est un peu difficile de définir comment créer une classe interne anonyme, nous verrons son utilisation en temps réel dans le programme de test ci-dessous.
Voici une classe Java montrant comment définir une classe interne Java, une classe imbriquée statique, une classe interne locale et une classe interne anonyme. OuterClass.java
package com.journaldev.nested;
import java.io.File;
import java.io.FilenameFilter;
public class OuterClass {
private static String name = "OuterClass";
private int i;
protected int j;
int k;
public int l;
//Constructeur OuterClass
public OuterClass(int i, int j, int k, int l) {
this.i = i;
this.j = j;
this.k = k;
this.l = l;
}
public int getI() {
return this.i;
}
//classe imbriquée statique, peut accéder aux variables/méthodes statiques d'OuterClass
static class StaticNestedClass {
private int a;
protected int b;
int c;
public int d;
public int getA() {
return this.a;
}
public String getName() {
return name;
}
}
//classe interne, non statique et peut accéder à toutes les variables/méthodes de la classe externe
class InnerClass {
private int w;
protected int x;
int y;
public int z;
public int getW() {
return this.w;
}
public void setValues() {
this.w = i;
this.x = j;
this.y = k;
this.z = l;
}
@Override
public String toString() {
return "w=" + w + ":x=" + x + ":y=" + y + ":z=" + z;
}
public String getName() {
return name;
}
}
//classe interne locale
public void print(String initial) {
//classe interne locale inside the method
class Logger {
String name;
public Logger(String name) {
this.name = name;
}
public void log(String str) {
System.out.println(this.name + ": " + str);
}
}
Logger logger = new Logger(initial);
logger.log(name);
logger.log("" + this.i);
logger.log("" + this.j);
logger.log("" + this.k);
logger.log("" + this.l);
}
//classe interne anonyme
public String[] getFilesInDir(String dir, final String ext) {
File file = new File(dir);
//classe interne anonyme implementing FilenameFilter interface
String[] filesList = file.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(ext);
}
});
return filesList;
}
}
Voici le programme de test montrant comment instancier et utiliser la classe interne en Java. InnerClassTest.java
package com.journaldev.nested;
import java.util.Arrays;
//les classes imbriquées peuvent être utilisées dans l'importation pour une instanciation facile
import com.journaldev.nested.OuterClass.InnerClass;
import com.journaldev.nested.OuterClass.StaticNestedClass;
public class InnerClassTest {
public static void main(String[] args) {
OuterClass outer = new OuterClass(1,2,3,4);
//exemple de classes imbriquées statiques
StaticNestedClass staticNestedClass = new StaticNestedClass();
StaticNestedClass staticNestedClass1 = new StaticNestedClass();
System.out.println(staticNestedClass.getName());
staticNestedClass.d=10;
System.out.println(staticNestedClass.d);
System.out.println(staticNestedClass1.d);
//exemple de classe interne
InnerClass innerClass = outer.new InnerClass();
System.out.println(innerClass.getName());
System.out.println(innerClass);
innerClass.setValues();
System.out.println(innerClass);
//appel de méthode à l'aide d'une classe interne locale
outer.print("Outer");
//appel de méthode à l'aide d'une classe interne anonyme
System.out.println(Arrays.toString(outer.getFilesInDir("src/com/journaldev/nested", ".java")));
System.out.println(Arrays.toString(outer.getFilesInDir("bin/com/journaldev/nested", ".class")));
}
}
Voici la sortie du programme d’exemple de classe interne Java ci-dessus.
OuterClass
10
0
OuterClass
w=0:x=0:y=0:z=0
w=1:x=2:y=3:z=4
Outer: OuterClass
Outer: 1
Outer: 2
Outer: 3
Outer: 4
[NestedClassTest.java, OuterClass.java]
[NestedClassTest.class, OuterClass$1.class, OuterClass$1Logger.class, OuterClass$InnerClass.class, OuterClass$StaticNestedClass.class, OuterClass.class]
Remarquez que lors de la compilation de OuterClass, des fichiers de classe distincts sont créés pour la classe interne, la classe interne locale et la classe imbriquée statique.
Avantages de la classe interne Java
- Si une classe est utile à une seule classe, il est logique de la garder imbriquée et ensemble. Cela facilite l’emballage des classes.
- Les classes internes Java implémentent l’encapsulation. Notez que les classes internes peuvent accéder aux membres privés de la classe externe et en même temps, nous pouvons masquer la classe interne du monde extérieur.
- Le fait de maintenir la petite classe à l’intérieur des classes de niveau supérieur place le code plus près de l’endroit où il est utilisé et rend le code plus lisible et plus maintenable.
C’est tout pour la classe interne Java.
Source:
https://www.digitalocean.com/community/tutorials/java-inner-class