Java geneste en inner classes meesteren: typen, voorbeelden en best practices
Java geneste en inner classes
Ontdek hoe Java's geneste klassen encapsulatie verbeteren, leesbaarheid verbeteren en krachtige inner-class patronen mogelijk maken.
In Java kun je een klasse binnen een andere klasse declareren – dit heet een geneste klasse. Bijvoorbeeld:
class OuterKlasse { // ... class GenesteKlasse { // ... } }
Er zijn twee hoofdsmaak van geneste klassen:
- Non-static geneste klasse (algemeen bekend als een inner class)
- Static geneste klasse
Aanbevolen lezing:
- Java toegangsmodificaties
- Java static sleutelwoord
Non-static geneste klasse (Inner class)
Een inner class bevindt zich binnen een outer klasse en kan vrij toegang tot de outer klasse's leden, zelfs private. Omdat het gebonden is aan een instantie van de outer klasse, moet je de outer klasse eerst instantiëren.
Voorbeeld 1: Inner class
class CPU { double prijs; // inner class class Processor{ double kernen; String fabrikant; double getCache(){ return 4.3; } } // protected inner class protected class RAM{ double geheugen; String fabrikant; double getKlokSnelheid(){ return 5.5; } } } public class Main { public static void main(String[] args) { CPU cpu = new CPU(); CPU.Processor processor = cpu.new Processor(); CPU.RAM ram = cpu.new RAM(); System.out.println("Processor Cache = " + processor.getCache()); System.out.println("Ram Kloksnelheid = " + ram.getKlokSnelheid()); } }
Uitvoer:
Processor Cache = 4.3 Ram Kloksnelheid = 5.5
Hier zijn Processor en RAM genest binnen CPU. De RAM klasse is gedeclareerd als protected, wat aantoont dat inner classes elke Java toegangsmodificatie kunnen gebruiken.
In Main instantiëren we eerst de outer klasse CPU, dan creëren we inner-klasse instanties via de outer instantie:
CPU.Processor processor = cpu.new Processor(); CPU.RAM ram = cpu.new RAM();
Tip: De punt (.) operator wordt gebruikt om een inner-klasse instantie te binden aan zijn outer instantie.
Leden van outer klasse benaderen vanuit een inner class
Inner classes kunnen de outer klasse's leden refereren via het this sleutelwoord gepréfixd met de outer klasse naam, bijv. Auto.this.autoType. Deze syntax is nodig wanneer de inner class zijn eigen this context heeft.
Voorbeeld 2: Interactie met de outer klasse
class Auto { String autoNaam; String autoType; public Auto(String naam, String type) { this.autoNaam = naam; this.autoType = type; } private String getAutoNaam() { return this.autoNaam; } // inner class class Motor { String motorType; void setMotor() { if(Auto.this.autoType.equals("4WD")){ if(Auto.this.getAutoNaam().equals("Chrysler")) { this.motorType = "Kleiner"; } else { this.motorType = "Groter"; } } else { this.motorType = "Groter"; } } String getMotorType(){ return this.motorType; } } } public class Main { public static void main(String[] args) { Auto auto1 = new Auto("Mazda", "8WD"); Auto.Motor motor = auto1.new Motor(); motor.setMotor(); System.out.println("Motor Type voor 8WD= " + motor.getMotorType()); Auto auto2 = new Auto("Chrysler", "4WD"); Auto.Motor c2motor = auto2.new Motor(); c2motor.setMotor(); System.out.println("Motor Type voor 4WD = " + c2motor.getMotorType()); } }
Uitvoer:
Motor Type voor 8WD= Groter Motor Type voor 4WD = Kleiner
Hoewel getAutoNaam() private is, kan de inner class het aanroepen omdat het binnen dezelfde outer klasse woont.
Statische geneste klasse
Een statische geneste klasse vereist geen instantie van de outer klasse om te worden gecreëerd. Daardoor kan het niet direct non-static leden van de outer klasse benaderen. Het wordt gecreëerd met de naam van de outer klasse:
OuterKlasse.GenesteKlasse obj = new OuterKlasse.GenesteKlasse();
Voorbeeld 3: Statische geneste klasse
class MoederBord { static class USB{ int usb2 = 2; int usb3 = 1; int getTotaalPoorten(){ return usb2 + usb3; } } } public class Main { public static void main(String[] args) { MoederBord.USB usb = new MoederBord.USB(); System.out.println("Totaal Poorten = " + usb.getTotaalPoorten()); } }
Uitvoer:
Totaal Poorten = 3
Voorbeeld 4: Poging outer leden te benaderen in een statische geneste klasse
class MoederBord { String model; public MoederBord(String model) { this.model = model; } static class USB{ int usb2 = 2; int usb3 = 1; int getTotaalPoorten(){ if(MoederBord.this.model.equals("MSI")) { return 4; } else { return usb2 + usb3; } } } } public class Main { public static void main(String[] args) { MoederBord.USB usb = new MoederBord.USB(); System.out.println("Totaal Poorten = " + usb.getTotaalPoorten()); } }
Deze code produceert:
error: non-static variable this cannot be referenced from a static context
Deze fout treedt op omdat de statische geneste klasse MoederBord.this niet kan refereren zonder een outer instantie.
Belangrijke takeaways
- Inner classes worden behandeld als gewone leden van de outer klasse en kunnen
private,protected, ofpublicgedeclareerd worden. - Ze kunnen vrij alle outer klasse leden benaderen, zelfs die gemarkeerd
private. - Statische geneste klassen vereisen geen outer instantie en kunnen non-static outer leden niet direct benaderen.
- Geneste klassen gebruiken bevordert encapsulatie en houdt gerelateerde logica gebundeld.
- Inner classes zijn ideaal voor callbacks, listeners, of helper objecten strak gekoppeld aan de outer klasse.
Java
- C# Geneste Classes: Definitie, Gebruik en Inheritance
- Java-variabelen en literals: een uitgebreide gids
- Java klassen en objecten: een praktische gids
- Java's final-sleutelwoord begrijpen: variabelen, methoden en klassen
- Java instanceof operator: een uitgebreide gids
- Java abstracte klassen en methoden: een uitgebreide gids
- Java geneste static classes begrijpen: gebruik, verschillen en voorbeelden
- Java anonieme inner classes meesteren: definitie, syntax en praktische voorbeelden
- Java Singleton patroon uitgelegd: hoe veilig te implementeren en gebruiken
- Java Reflectie meesteren: klassen, methoden en velden inspecteren tijdens runtime
- Java Generics: Herbruikbare, type-veilige code bouwen