Menguasai Kelas Bersarang dan Kelas Dalam Java: Jenis, Contoh, dan Praktik Terbaik
Kelas Bersarang dan Kelas Dalam Java
Temukan bagaimana kelas bersarang Java meningkatkan enkapsulasi, meningkatkan keterbacaan, dan memungkinkan pola kelas dalam yang canggih.
Di Java Anda dapat mendeklarasikan kelas di dalam kelas lain—ini disebut nested class. Misalnya:
class OuterClass { // ... class NestedClass { // ... } }
Ada dua macam utama nested classes:
- Non-static nested class (umumnya dikenal sebagai inner class)
- Static nested class
Bacaan yang direkomendasikan:
- Java Access Modifiers
- Java Static Keyword
Non-Static Nested Class (Inner Class)
Sebuah inner class berada di dalam outer class dan dapat secara bebas mengakses anggota outer class, bahkan yang private. Karena ia terikat pada instance outer class, Anda harus menginstantiasi outer class terlebih dahulu.
Contoh 1: Inner Class
class CPU { double price; // inner class class Processor{ double cores; String manufacturer; double getCache(){ return 4.3; } } // protected inner class protected class RAM{ double memory; String manufacturer; double getClockSpeed(){ 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 Clock speed = " + ram.getClockSpeed()); } }
Output:
Processor Cache = 4.3 Ram Clock speed = 5.5
Di sini, Processor dan RAM bersarang dalam CPU. Kelas RAM dideklarasikan protected, menunjukkan bahwa inner class dapat menggunakan access modifier Java apa pun.
Di Main, kita pertama-tama menginstantiasi outer class CPU, lalu membuat instance inner class melalui instance outer:
CPU.Processor processor = cpu.new Processor; CPU.RAM ram = cpu.new RAM();
Tips: Operator titik (.) digunakan untuk mengikat instance inner class ke instance outer.
Mengakses Anggota Outer Class dari Inner Class
Inner class dapat mereferensikan anggota outer class melalui kata kunci this yang diawali dengan nama outer class, misalnya, Car.this.carType. Sintaks ini diperlukan saat inner class memiliki konteks this sendiri.
Contoh 2: Berinteraksi dengan Outer Class
class Car { String carName; String carType; public Car(String name, String type) { this.carName = name; this.carType = type; } private String getCarName() { return this.carName; } // inner class class Engine { String engineType; void setEngine() { if(Car.this.carType.equals("4WD")){ if(Car.this.getCarName().equals("Crysler")) { this.engineType = "Smaller"; } else { this.engineType = "Bigger"; } } else { this.engineType = "Bigger"; } } String getEngineType(){ return this.engineType; } } } public class Main { public static void main(String[] args) { Car car1 = new Car("Mazda", "8WD"); Car.Engine engine = car1.new Engine(); engine.setEngine(); System.out.println("Engine Type for 8WD= " + engine.getEngineType()); Car car2 = new Car("Crysler", "4WD"); Car.Engine c2engine = car2.new Engine(); c2engine.setEngine(); System.out.println("Engine Type for 4WD = " + c2engine.getEngineType()); } }
Output:
Engine Type for 8WD= Bigger Engine Type for 4WD = Smaller
Meskipun getCarName() adalah private, inner class dapat memanggilnya karena ia berada dalam outer class yang sama.
Static Nested Class
Sebuah static nested class tidak memerlukan instance outer class untuk dibuat. Akibatnya, ia tidak dapat langsung mengakses anggota non-static outer class. Ia dibuat menggunakan nama outer class:
OuterClass.NestedClass obj = new OuterClass.NestedClass();
Contoh 3: Static Nested Class
class MotherBoard { static class USB{ int usb2 = 2; int usb3 = 1; int getTotalPorts(){ return usb2 + usb3; } } } public class Main { public static void main(String[] args) { MotherBoard.USB usb = new MotherBoard.USB(); System.out.println("Total Ports = " + usb.getTotalPorts()); } }
Output:
Total Ports = 3
Contoh 4: Mencoba Mengakses Anggota Outer di Static Nested Class
class MotherBoard { String model; public MotherBoard(String model) { this.model = model; } static class USB{ int usb2 = 2; int usb3 = 1; int getTotalPorts(){ if(MotherBoard.this.model.equals("MSI")) { return 4; } else { return usb2 + usb3; } } } } public class Main { public static void main(String[] args) { MotherBoard.USB usb = new MotherBoard.USB(); System.out.println("Total Ports = " + usb.getTotalPorts()); } }
Menjalankan kode ini menghasilkan:
error: non-static variable this cannot be referenced from a static context
Kesalahan ini terjadi karena static nested class tidak dapat mereferensikan MotherBoard.this tanpa instance outer.
Kesalahan Utama
- Inner class diperlakukan sebagai anggota reguler outer class dan dapat dideklarasikan
private, protected, atau public. - Mereka dapat secara bebas mengakses semua anggota outer class, bahkan yang ditandai
private. - Static nested class tidak memerlukan instance outer dan tidak dapat mengakses anggota non-static outer secara langsung.
- Menggunakan nested classes mempromosikan enkapsulasi dan menjaga logika terkait tetap bersama.
- Inner class ideal untuk callback, listener, atau objek helper yang terikat erat dengan outer class.