Java-Innere Klasse ist innerhalb des Körpers einer anderen Klasse definiert. Java-Innere Klasse kann als private, public, protected oder mit Standardzugriff deklariert werden, während eine äußere Klasse nur öffentlichen oder Standardzugriff haben kann. Java-verschachtelte Klassen werden in zwei Typen unterteilt.
-
Statische verschachtelte Klasse
Wenn die verschachtelte Klasse statisch ist, wird sie als statische verschachtelte Klasse bezeichnet. Statische verschachtelte Klassen können nur auf statische Elemente der äußeren Klasse zugreifen. Eine statische verschachtelte Klasse ist genauso wie jede andere Top-Level-Klasse und ist nur zur Verpackungskomfort verschachtelt. Ein statisches Klassenobjekt kann mit folgender Anweisung erstellt werden.
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
-
Java-Innere Klasse
Jede nicht-statische verschachtelte Klasse wird in Java als innere Klasse bezeichnet. Java-Innere Klassen sind mit dem Objekt der Klasse verbunden und können auf alle Variablen und Methoden der äußeren Klasse zugreifen. Da innere Klassen mit der Instanz verbunden sind, können wir keine statischen Variablen darin haben. Die Objekte der Java-Inneren Klasse sind Teil des äußeren Klassenobjekts, und um eine Instanz der inneren Klasse zu erstellen, müssen wir zuerst eine Instanz der äußeren Klasse erstellen. Java-Innere Klassen können wie folgt instanziiert werden;
OuterClass outerObject = new OuterClass(); OuterClass.InnerClass innerObject = outerObject.new InnerClass();
Es gibt zwei besondere Arten von Java-Inneren Klassen.
-
Lokale innere Klasse
Wenn eine Klasse in einem Methodenkörper definiert wird, wird sie als lokale innere Klasse bezeichnet. Da die lokale innere Klasse nicht mit dem Objekt verknüpft ist, können wir private, public oder geschützte Zugriffsmodifizierer nicht verwenden. Die einzigen erlaubten Modifizierer sind abstract oder final. Eine lokale innere Klasse kann auf alle Member der umgebenden Klasse und auf lokale endgültige Variablen im Bereich, in dem sie definiert ist, zugreifen. Darüber hinaus kann sie auch auf eine nicht endgültige lokale Variable der Methode zugreifen, in der sie definiert ist, aber sie kann sie nicht ändern. Wenn Sie also den Wert einer nicht endgültigen lokalen Variablen ausgeben möchten, ist dies erlaubt, aber wenn Sie versuchen, den Wert von innerhalb der Methode lokaler innerer Klasse aus zu ändern, erhalten Sie einen Kompilierungsfehler. Eine lokale innere Klasse kann wie folgt definiert werden:
Paket com.journaldev.innerclasses; public class MainClass { private String s_main_class; public void drucken() { String s_print_method = ""; // Lokale innere Klasse innerhalb der Methode class Logger { // Zugriff auf umgebende Klassenvariablen möglich String name = s_main_class; // Zugriff auf nicht endgültige Methodenvariablen möglich String name1 = s_print_method; public void foo() { String name1 = s_print_method; // Der folgende Code führt zu einem Kompilierungsfehler: // Lokale Variable s_print_method, die in einem umgebenden Bereich definiert ist, muss final oder effektiv final sein // s_print_method= ":"; } } // Instantiierung der lokalen inneren Klasse in der Methode zur Verwendung Logger logger = new Logger(); } }
Wir können auch eine lokale innere Klasse in jedem Block definieren, z.B. statischer Block, if-else-Block usw. In diesem Fall ist der Gültigkeitsbereich der Klasse jedoch sehr begrenzt.
public class MainClass { static { class Foo { } Foo f = new Foo(); } public void bar() { if(1 < 2) { class Test { } Test t1 = new Test(); } // Der folgende Code führt aufgrund des Gültigkeitsbereichs der Klasse zu einem Fehler //Test t = new Test(); //Foo f = new Foo(); } }
-
anonyme innere Klasse
Eine lokale innere Klasse ohne Namen wird als anonyme innere Klasse bezeichnet. Eine anonyme Klasse wird in einer einzigen Anweisung definiert und instanziiert. Anonyme innere Klassen erweitern immer eine Klasse oder implementieren ein Interface. Da eine anonyme Klasse keinen Namen hat, ist es nicht möglich, einen Konstruktor für eine anonyme Klasse zu definieren. Anonyme innere Klassen sind nur an der Stelle zugänglich, an der sie definiert werden. Es ist etwas schwierig zu definieren, wie man eine anonyme innere Klasse erstellt. Wir werden ihren Echtzeiteinsatz im untenstehenden Testprogramm sehen.
Hier ist eine Java-Klasse, die zeigt, wie man eine Java-Innere Klasse, eine statische verschachtelte Klasse, eine lokale innere Klasse und eine anonyme innere Klasse definiert. 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;
//Konstruktor der äußeren Klasse
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;
}
//Statisch verschachtelte Klasse, kann auf statische Variablen/Methoden der äußeren Klasse zugreifen
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;
}
}
//Innere Klasse, nicht statisch und kann auf alle Variablen/Methoden der äußeren Klasse zugreifen
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;
}
}
//Lokale innere Klasse
public void print(String initial) {
//Lokale innere Klasse 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);
}
//Anonyme innere Klasse
public String[] getFilesInDir(String dir, final String ext) {
File file = new File(dir);
//Anonyme innere Klasse implementing FilenameFilter interface
String[] filesList = file.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(ext);
}
});
return filesList;
}
}
Hier ist das Testprogramm, das zeigt, wie man die innere Klasse in Java instanziiert und verwendet. InnerClassTest.java
package com.journaldev.nested;
import java.util.Arrays;
//Verschachtelte Klassen können beim Import verwendet werden, um eine einfache Instanziierung zu ermöglichen
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);
//Beispiel für statisch verschachtelte Klassen
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);
//Beispiel für innere Klasse
InnerClass innerClass = outer.new InnerClass();
System.out.println(innerClass.getName());
System.out.println(innerClass);
innerClass.setValues();
System.out.println(innerClass);
//Aufruf der Methode unter Verwendung einer lokalen inneren Klasse
outer.print("Outer");
//Aufruf der Methode unter Verwendung einer anonymen inneren Klasse
System.out.println(Arrays.toString(outer.getFilesInDir("src/com/journaldev/nested", ".java")));
System.out.println(Arrays.toString(outer.getFilesInDir("bin/com/journaldev/nested", ".class")));
}
}
Hier ist die Ausgabe des oben genannten Java-Inner-Klassenbeispielprogramms.
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]
Beachten Sie, dass beim Kompilieren der äußeren Klasse separate Klassendateien für die innere Klasse, die lokale innere Klasse und die statisch verschachtelte Klasse erstellt werden.
Vorteile der Java-Innerklasse
- Wenn eine Klasse nur für eine Klasse nützlich ist, macht es Sinn, sie verschachtelt und zusammenzuhalten. Es hilft bei der Verpackung der Klassen.
- Java Innere Klassen implementieren die Kapselung. Beachten Sie, dass Innere Klassen auf private Mitglieder der äußeren Klasse zugreifen können und gleichzeitig können wir die Innere Klasse vor der äußeren Welt verbergen.
- Das Halten der kleinen Klasse innerhalb von Top-Level-Klassen platziert den Code näher an der Stelle, an der er verwendet wird, und macht den Code lesbarer und wartbarer.
Das ist alles für Java Innere Klassen.
Source:
https://www.digitalocean.com/community/tutorials/java-inner-class