Java verschachtelte und innere Klassen meistern: Typen, Beispiele und Best Practices
Java verschachtelte und innere Klassen
Entdecken Sie, wie Javas verschachtelte Klassen Kapselung verbessern, Lesbarkeit erhöhen und mächtige Inner-Class-Muster ermöglichen.
In Java können Sie eine Klasse innerhalb einer anderen Klasse deklarieren – dies wird verschachtelte Klasse genannt. Zum Beispiel:
class AussenKlasse { // ... class VerschachtelteKlasse { // ... } }
Es gibt zwei Hauptarten verschachtelter Klassen:
- Nicht-statische verschachtelte Klasse (üblicherweise als innere Klasse bekannt)
- Statische verschachtelte Klasse
Empfohlene Lektüre:
- Java-Zugriffsmodifikatoren
- Java Static-Schlüsselwort
Nicht-statische verschachtelte Klasse (Innere Klasse)
Eine innere Klasse befindet sich innerhalb einer äußeren Klasse und kann frei auf die Member der äußeren Klasse zugreifen, sogar auf private. Da sie an eine Instanz der äußeren Klasse gebunden ist, müssen Sie zuerst die äußere Klasse instanziieren.
Beispiel 1: Innere Klasse
class CPU { double preis; // innere class Prozessor{ double kerne; String hersteller; double cacheAbrufen(){ return 4.3; } } // protected innere Klasse protected class RAM{ double speicher; String hersteller; double taktrateAbrufen(){ return 5.5; } } } public class Haupt { public static void main(String[] args) { CPU cpu = new CPU(); CPU.Prozessor prozessor = cpu.new Prozessor(); CPU.RAM ram = cpu.new RAM(); System.out.println("Prozessor Cache = " + prozessor.cacheAbrufen()); System.out.println("RAM Taktrate = " + ram.taktrateAbrufen()); } }
Ausgabe:
Prozessor Cache = 4.3 RAM Taktrate = 5.5
Hier sind Prozessor und RAM innerhalb von CPU verschachtelt. Die RAM-Klasse ist als protected deklariert, was zeigt, dass innere Klassen jeden Java-Zugriffsmodifikator verwenden können.
In Haupt instanziieren wir zuerst die äußere Klasse CPU, dann erstellen wir Inner-Class-Instanzen über die äußere Instanz:
CPU.Prozessor prozessor = cpu.new Prozessor(); CPU.RAM ram = cpu.new RAM();
Tipp: Der Punkt-Operator (.) wird verwendet, um eine Inner-Class-Instanz an ihre äußere Instanz zu binden.
Auf Member der äußeren Klasse aus einer inneren Klasse zugreifen
Innere Klassen können Member der äußeren Klasse über das this-Schlüsselwort referenzieren, präfixiert mit dem Namen der äußeren Klasse, z. B. Auto.this.autoTyp. Diese Syntax ist notwendig, wenn die innere Klasse ihren eigenen this-Kontext hat.
Beispiel 2: Interaktion mit der äußeren Klasse
class Auto { String autoName; String autoTyp; public Auto(String name, String typ) { this.autoName = name; this.autoTyp = typ; } private String autoNameAbrufen() { return this.autoName; } // innere Klasse class Motor { String motorTyp; void motorSetzen() { if(Auto.this.autoTyp.equals("4WD")){ if(Auto.this.autoNameAbrufen().equals("Chrysler")) { this.motorTyp = "Kleiner"; } else { this.motorTyp = "Größer"; } } else { this.motorTyp = "Größer"; } } String motorTypAbrufen(){ return this.motorTyp; } } } public class Haupt { public static void main(String[] args) { Auto auto1 = new Auto("Mazda", "8WD"); Auto.Motor motor = auto1.new Motor(); motor.motorSetzen(); System.out.println("Motor Typ für 8WD = " + motor.motorTypAbrufen()); Auto auto2 = new Auto("Chrysler", "4WD"); Auto.Motor a2motor = auto2.new Motor(); a2motor.motorSetzen(); System.out.println("Motor Typ für 4WD = " + a2motor.motorTypAbrufen()); } }
Ausgabe:
Motor Typ für 8WD = Größer Motor Typ für 4WD = Kleiner
Obwohl autoNameAbrufen() private ist, kann die innere Klasse sie aufrufen, da sie innerhalb derselben äußeren Klasse residiert.
Statische verschachtelte Klasse
Eine statische verschachtelte Klasse erfordert keine Instanz der äußeren Klasse zur Erstellung. Folglich kann sie nicht direkt auf nicht-statische Member der äußeren Klasse zugreifen. Sie wird mit dem Namen der äußeren Klasse erstellt:
AussenKlasse.VerschachtelteKlasse obj = new AussenKlasse.VerschachtelteKlasse();
Beispiel 3: Statische verschachtelte Klasse
class Hauptplatine { static class USB{ int usb2 = 2; int usb3 = 1; int gesamtPortsAbrufen(){ return usb2 + usb3; } } } public class Haupt { public static void main(String[] args) { Hauptplatine.USB usb = new Hauptplatine.USB(); System.out.println("Gesamt Ports = " + usb.gesamtPortsAbrufen()); } }
Ausgabe:
Gesamt Ports = 3
Beispiel 4: Versuch, äußere Member in einer statischen verschachtelten Klasse zuzugreifen
class Hauptplatine { String modell; public Hauptplatine(String modell) { this.modell = modell; } static class USB{ int usb2 = 2; int usb3 = 1; int gesamtPortsAbrufen(){ if(Hauptplatine.this.modell.equals("MSI")) { return 4; } else { return usb2 + usb3; } } } } public class Haupt { public static void main(String[] args) { Hauptplatine.USB usb = new Hauptplatine.USB(); System.out.println("Gesamt Ports = " + usb.gesamtPortsAbrufen()); } }
Die Ausführung dieses Codes produziert:
error: non-static variable this cannot be referenced from a static context
Dieser Fehler tritt auf, weil die statische verschachtelte Klasse Hauptplatine.this ohne äußere Instanz nicht referenzieren kann.
Wichtige Erkenntnisse
- Innere Klassen werden als reguläre Member der äußeren Klasse behandelt und können als
private,protectedoderpublicdeklariert werden. - Sie können frei auf alle Member der äußeren Klasse zugreifen, sogar auf
privatemarkierte. - Statische verschachtelte Klassen benötigen keine äußere Instanz und können nicht direkt auf nicht-statische äußere Member zugreifen.
- Die Verwendung verschachtelter Klassen fördert Kapselung und hält verwandte Logik gebündelt.
- Innere Klassen eignen sich ideal für Callbacks, Listener oder Helper-Objekte, die eng an die äußere Klasse gekoppelt sind.
Java
- C# Geschachtelte Klassen verstehen: Definition, Verwendung und Vererbung
- Java Variablen und Literale: Umfassender Leitfaden
- Java Klassen und Objekte: Praktischer Leitfaden
- Javas final-Schlüsselwort verstehen: Variablen, Methoden und Klassen
- Java instanceof-Operator: Ein umfassender Leitfaden
- Java abstrakte Klassen und Methoden: Ein umfassender Leitfaden
- Java statische verschachtelte Klassen verstehen: Nutzung, Unterschiede und Beispiele
- Java anonyme innere Klassen meistern: Definition, Syntax und praktische Beispiele
- Java Singleton-Pattern erklärt: Sichere Implementierung und Verwendung
- Java Reflection meistern: Klassen, Methoden und Felder zur Laufzeit inspizieren