class OuterClass {
...
static class StaticNestedClass {
...
}
class InnerClass {
...
}
}
Kelas internal ini disebut bersarang. Mereka dibagi menjadi 2 jenis:
- Kelas bersarang non-statis. Ini juga disebut kelas batin.
- Kelas bersarang statis.
- kelas lokal
- kelas tanpa nama
public class Bicycle {
private String model;
private int weight;
public Bicycle(String model, int weight) {
this.model = model;
this.weight = weight;
}
public void start() {
System.out.println("Let's go!");
}
public class Handlebar {
public void right() {
System.out.println("Steer right!");
}
public void left() {
System.out.println("Steer left!");
}
}
public class Seat {
public void up() {
System.out.println("Seat up!");
}
public void down() {
System.out.println("Seat down!");
}
}
}
Di sini kita memiliki Bicycle
kelas. Ini memiliki 2 bidang dan 1 metode: start()
. Ini berbeda dari kelas biasa karena berisi dua kelas: Handlebar
dan Seat
. Kode mereka ditulis di dalam Bicycle
kelas. Ini adalah kelas yang lengkap: seperti yang Anda lihat, masing-masing memiliki metodenya sendiri. Pada titik ini, Anda mungkin memiliki pertanyaan: mengapa kita menempatkan satu kelas di dalam yang lain? Mengapa menjadikan mereka kelas dalam? Nah, misalkan kita membutuhkan kelas terpisah untuk konsep stang dan jok dalam program kita. Tentu saja, kita tidak perlu membuatnya bersarang! Kita bisa membuat kelas biasa. Misalnya, seperti ini:
public class Handlebar {
public void right() {
System.out.println("Steer right!");
}
public void left() {
System.out.println("Steer left");
}
}
public class Seat {
public void up() {
System.out.println("Seat up!");
}
public void down() {
System.out.println("Seat down!");
}
}
Pertanyaan yang sangat bagus! Tentu saja, kita tidak dibatasi oleh teknologi. Melakukan itu tentu saja merupakan pilihan. Di sini, yang lebih penting adalah desain kelas yang benar dari perspektif program tertentu dan tujuannya. Kelas dalam adalah untuk memisahkan entitas yang terhubung erat ke entitas lain. Setang, jok, dan pedal adalah komponen sepeda. Terpisah dari sepeda, mereka tidak masuk akal. Jika kami membuat semua konsep ini memisahkan kelas publik, kami akan memiliki kode seperti ini di program kami:
public class Main {
public static void main(String[] args) {
Handlebar handlebar = new Handlebar();
handlebar.right();
}
}
Hmm... Arti dari kode ini malah sulit untuk dijelaskan. Kami memiliki beberapa stang yang tidak jelas (Mengapa perlu? Tidak tahu, jujur saja). Dan pegangan ini berbelok ke kanan... dengan sendirinya, tanpa sepeda... untuk beberapa alasan. Dengan memisahkan konsep stang dari konsep sepeda, kami kehilangan logika dalam program kami. Menggunakan kelas dalam, kodenya terlihat sangat berbeda:
public class Main {
public static void main(String[] args) {
Bicycle peugeot = new Bicycle("Peugeot", 120);
Bicycle.Handlebar handlebar = peugeot.new Handlebar();
Bicycle.Seat seat = peugeot.new Seat();
seat.up();
peugeot.start();
handlebar.left();
handlebar.right();
}
}
Keluaran konsol:
Seat up!
Let's go!
Steer left!
Steer right!
Sekarang apa yang kita lihat tiba-tiba masuk akal! :) Kami membuat objek sepeda. Kami membuat dua "subobjek" sepeda — setang dan kursi. Kami mengangkat kursi untuk kenyamanan dan kami berangkat: mengayuh dan menyetir sesuai kebutuhan! :) Metode yang kita butuhkan dipanggil pada objek yang sesuai. Semuanya sederhana dan nyaman. Dalam contoh ini, memisahkan stang dan jok meningkatkan enkapsulasi (kami menyembunyikan data tentang suku cadang sepeda di dalam kelas yang relevan) dan memungkinkan kami membuat abstraksi yang lebih mendetail. Sekarang mari kita lihat situasi yang berbeda. Misalkan kita ingin membuat program yang mensimulasikan toko sepeda dan suku cadang sepeda. Dalam situasi ini, solusi kami sebelumnya tidak akan berfungsi. Di toko sepeda, setiap bagian sepeda masuk akal meskipun dipisahkan dari sepeda. Misalnya, kita memerlukan metode seperti "menjual pedal ke pelanggan", "membeli kursi baru", dll. Akan menjadi kesalahan untuk menggunakan kelas dalam di sini — setiap bagian sepeda dalam program baru kita memiliki arti yang berdiri di sendiri: dapat dipisahkan dari konsep sepeda. Inilah yang perlu Anda perhatikan jika Anda bertanya-tanya apakah Anda harus menggunakan kelas dalam atau mengatur semua entitas sebagai kelas terpisah. Pemrograman berorientasi objek bagus karena memudahkan untuk memodelkan entitas dunia nyata. Ini bisa menjadi prinsip panduan Anda saat memutuskan apakah akan menggunakan kelas batin. Di toko nyata, suku cadang terpisah dari sepeda — tidak apa-apa. Artinya juga oke saat mendesain program. Oke, kami telah menemukan "filosofi" :) Sekarang mari berkenalan dengan fitur "teknis" penting dari kelas dalam. Inilah yang pasti perlu Anda ingat dan pahami:
-
Objek kelas dalam tidak bisa ada tanpa objek kelas luar.
Ini masuk akal: inilah mengapa kami membuat kelas dalam
Seat
danHandlebar
dalam program kami — sehingga kami tidak berakhir dengan setang dan kursi yatim piatu.Kode ini tidak dapat dikompilasi:
public static void main(String[] args) { Handlebar handlebar = new Handlebar(); }
Fitur penting lainnya mengikuti dari ini:
-
Objek kelas dalam memiliki akses ke variabel kelas luar.
Sebagai contoh, mari tambahkan
int seatPostDiameter
variabel (mewakili diameter seatpost) keBicycle
kelas kita.Kemudian di
Seat
kelas dalam, kita bisa membuatdisplaySeatProperties()
metode yang menampilkan properti kursi:public class Bicycle { private String model; private int weight; private int seatPostDiameter; public Bicycle(String model, int weight, int seatPostDiameter) { this.model = model; this.weight = weight; this.seatPostDiameter = seatPostDiameter; } public void start() { System.out.println("Let's go!"); } public class Seat { public void up() { System.out.println("Seat up!"); } public void down() { System.out.println("Seat down!"); } public void displaySeatProperties() { System.out.println("Seat properties: seatpost diameter = " + Bicycle.this.seatPostDiameter); } } }
Dan sekarang kami dapat menampilkan informasi ini di program kami:
public class Main { public static void main(String[] args) { Bicycle bicycle = new Bicycle("Peugeot", 120, 40); Bicycle.Seat seat = bicycle.new Seat(); seat.displaySeatProperties(); } }
Keluaran konsol:
Seat properties: seatpost diameter = 40
Catatan:variabel baru dideklarasikan dengan pengubah akses paling ketat (
private
). Dan tetap saja kelas dalam memiliki akses! -
Objek kelas dalam tidak dapat dibuat dalam metode statis kelas luar.
Ini dijelaskan oleh ciri-ciri khusus tentang bagaimana kelas dalam diatur. Kelas dalam dapat memiliki konstruktor dengan parameter, atau hanya konstruktor default. Namun terlepas dari itu, saat kita membuat objek kelas dalam, referensi ke objek kelas luar tidak terlihat diteruskan ke objek kelas dalam yang dibuat. Toh, keberadaan referensi objek semacam itu merupakan syarat mutlak. Jika tidak, kita tidak akan dapat membuat objek kelas dalam.
Tetapi jika metode kelas luar bersifat statis, maka kita mungkin tidak memiliki objek kelas luar! Dan ini akan menjadi pelanggaran logika tentang cara kerja kelas dalam. Dalam situasi ini, kompiler akan menghasilkan kesalahan:
public static Seat createSeat() { // Bicycle.this cannot be referenced from a static context return new Seat(); }
-
Kelas dalam tidak dapat berisi variabel dan metode statis.
Logikanya sama: metode dan variabel statis dapat ada dan dipanggil atau direferensikan bahkan tanpa adanya objek.
Tetapi tanpa objek kelas luar, kita tidak akan memiliki akses ke kelas dalam.
Kontradiksi yang jelas! Inilah sebabnya mengapa variabel dan metode statis tidak diperbolehkan di kelas dalam.
Kompiler akan menghasilkan kesalahan jika Anda mencoba membuatnya:
public class Bicycle { private int weight; public class Seat { // An inner class cannot have static declarations public static void displaySeatProperties() { System.out.println("Seat properties: seatpost diameter = " + Bicycle.this.seatPostDiameter); } } }
-
Saat membuat objek kelas dalam, pengubah aksesnya penting.
Kelas dalam dapat ditandai dengan pengubah akses standar:
public
,private
,protected
, danpackage private
.Mengapa ini penting?
Ini memengaruhi di mana kita dapat membuat instance kelas dalam dalam program kita.
Jika
Seat
kelas kita dideklarasikan sebagaipublic
, kita dapat membuatSeat
objek di kelas lain mana pun. Satu-satunya persyaratan adalah objek kelas luar juga harus ada.Omong-omong, kami sudah melakukan ini di sini:
public class Main { public static void main(String[] args) { Bicycle peugeot = new Bicycle("Peugeot", 120); Bicycle.Handlebar handlebar = peugeot.new Handlebar(); Bicycle.Seat seat = peugeot.new Seat(); seat.up(); peugeot.start(); handlebar.left(); handlebar.right(); } }
Kami dengan mudah mendapatkan akses ke
Handlebar
kelas dalam dariMain
kelas.Jika kita mendeklarasikan kelas dalam sebagai
private
, kita hanya dapat membuat objek di dalam kelas luar.Kita tidak bisa lagi membuat
Seat
objek "di luar":private class Seat { // Methods } public class Main { public static void main(String[] args) { Bicycle bicycle = new Bicycle("Peugeot", 120, 40); // Bicycle.Seat has private access in Bicycle Bicycle.Seat seat = bicycle.new Seat(); } }
Anda mungkin sudah mengerti logikanya :)
-
Pengubah akses untuk kelas dalam bekerja sama dengan variabel biasa.
Pengubah
protected
menyediakan akses ke variabel instan dalam subkelas dan kelas yang berada dalam paket yang sama.protected
juga berfungsi untuk kelas dalam. Kita dapat membuatprotected
objek kelas dalam:- di kelas luar;
- dalam subkelasnya;
- di kelas yang berada dalam paket yang sama.
Jika kelas dalam tidak memiliki pengubah akses (
package private
), objek kelas dalam dapat dibuat:- di kelas luar;
- di kelas yang berada dalam paket yang sama.
Anda sudah lama mengenal pengubah, jadi tidak ada masalah di sini.
GO TO FULL VERSION