class OuterClass {
...
static class StaticNestedClass {
...
}
class InnerClass {
...
}
}
Kelas-kelas inilah yang disebut bersarang. Mereka dibagi menjadi 2 jenis:
- Kelas bersarang non-statis - kelas bersarang non-statis. Mereka juga disebut kelas dalam dengan cara lain.
- Kelas bersarang statis - kelas bersarang statis.
- kelas lokal
- kelas anonim
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("Go!");
}
public class HandleBar {
public void right() {
System.out.println("Steering wheel to the right!");
}
public void left() {
System.out.println("Steering wheel to the left!");
}
}
public class Seat {
public void up() {
System.out.println("The seat is up!");
}
public void down() {
System.out.println("The seat is down!");
}
}
}
Di sini kita memiliki kelas Bicycle
- sepeda. Ini memiliki 2 bidang dan 1 metode - start()
. Perbedaannya dengan kelas biasa adalah ia memiliki dua kelas, yang kodenya tertulis di dalamnya Bicycle
, yaitu kelas HandleBar
(roda kemudi) dan Seat
(kursi). Ini adalah kelas yang lengkap: seperti yang Anda lihat, masing-masing kelas memiliki metodenya sendiri. Pada titik ini, Anda mungkin mempunyai pertanyaan: mengapa kami menempatkan satu kelas di dalam kelas lain? Mengapa menjadikannya internal? Oke, misalkan kita memerlukan kelas terpisah untuk setir dan jok dalam program. Namun Anda tidak perlu menumpuknya! Anda bisa membuat kelas reguler. Misalnya seperti ini:
public class HandleBar {
public void right() {
System.out.println("Steering wheel to the right!");
}
public void left() {
System.out.println("Steering wheel left");
}
}
public class Seat {
public void up() {
System.out.println("The seat is up!");
}
public void down() {
System.out.println("The seat is down!");
}
}
Pertanyaan yang sangat bagus! Tentu saja, kami tidak memiliki batasan teknis - kami dapat melakukannya dengan cara ini. Ini lebih tentang merancang kelas dengan benar dari sudut pandang program tertentu dan dalam arti program itu. Kelas dalam adalah kelas untuk menyorot entitas tertentu dalam suatu program yang terkait erat dengan entitas lain. Setir, jok, pedal merupakan komponen-komponen sepeda. Dipisahkan dari sepeda, hal itu tidak masuk akal. Jika kita membuat semua kelas ini menjadi kelas publik yang terpisah, program kita dapat memiliki, misalnya, kode berikut:
public class Main {
public static void main(String[] args) {
HandleBar handleBar = new HandleBar();
handleBar.right();
}
}
Ummm... Arti kode ini malah sulit dijelaskan. Kami memiliki semacam stang sepeda yang aneh (mengapa diperlukan? Sejujurnya tidak tahu). Dan setir ini berbelok ke kanan... sendiri, tanpa sepeda... entah kenapa. Dengan memisahkan esensi roda kemudi dari esensi sepeda, kita telah kehilangan logika program kita. 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:
Сиденье поднято выше!
Поехали!
Руль влево!
Руль вправо!
Apa yang terjadi tiba-tiba menjadi masuk akal! :) Kita telah membuat objek sepeda. Kami menciptakan dua "subobjek" - roda kemudi dan kursi. Kami menaikkan kursi lebih tinggi untuk kenyamanan - dan kami berangkat: kami berguling dan mengarahkan ke mana pun kami harus pergi! :) Metode yang kita perlukan dipanggil pada objek yang diperlukan. Semuanya sederhana dan nyaman. Dalam contoh ini, menyorot setang dan jok akan meningkatkan enkapsulasi (kita menyembunyikan data tentang bagian-bagian sepeda dalam kelas yang sesuai), dan memungkinkan kita membuat abstraksi yang lebih detail. Sekarang mari kita lihat situasi lain. Katakanlah kita ingin membuat program yang memodelkan sepeda dan toko suku cadang. Dalam situasi ini, solusi kami sebelumnya akan gagal. Dalam lingkup toko suku cadang, setiap bagian dari sepeda memiliki makna meskipun terlepas dari esensi sepeda. Misalnya, kita memerlukan metode seperti “jual pedal ke pembeli”, “beli kursi baru”, dll. Akan menjadi kesalahan jika menggunakan kelas internal di sini - setiap bagian sepeda dalam program baru kami memiliki arti tersendiri: terpisah dari esensi sepeda, dan sama sekali tidak terikat padanya. Inilah yang harus Anda perhatikan jika Anda bertanya-tanya apakah Anda perlu menggunakan kelas dalam, atau memisahkan semua entitas ke dalam kelas terpisah. Pemrograman berorientasi objek sangat bagus karena memudahkan pemodelan entitas dunia nyata. Inilah yang dapat Anda gunakan sebagai panduan ketika memutuskan apakah akan menggunakan kelas batin. Di toko sungguhan, suku cadangnya terpisah dari sepeda - ini normal. Artinya ini akan benar ketika merancang suatu program. Oke, kita sudah memilah “filosofinya” :) Sekarang mari kita berkenalan dengan fitur “teknis” penting dari kelas dalam. Inilah yang pasti perlu Anda ingat dan pahami:
-
Sebuah objek dari kelas dalam tidak dapat ada tanpa objek dari kelas “luar”.
Ini logis: itulah sebabnya kami menjadikannya kelas
Seat
internalHandleBar
, sehingga roda kemudi dan kursi tanpa pemilik tidak akan muncul di sana-sini dalam program kami.Kode ini tidak dapat dikompilasi:
public static void main(String[] args) { HandleBar handleBar = new HandleBar(); }
Fitur penting berikut ini mengikuti dari ini:
-
Sebuah objek dari kelas dalam memiliki akses ke variabel kelas "luar".
Sebagai contoh, mari tambahkan
Bicycle
variabel ke kelas kitaint seatPostDiameter
- diameter tiang pengaman.Kemudian di kelas dalam
Seat
kita dapat membuat metodegetSeatParam()
yang akan memberi tahu kita parameter 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("Go!"); } public class Seat { public void up() { System.out.println("The seat is up!"); } public void down() { System.out.println("The seat is down!"); } public void getSeatParam() { System.out.println("Seat parameter: seatpost diameter = " + Bicycle.this.seatPostDiameter); } } }
Dan sekarang kami bisa mendapatkan 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.getSeatParam(); } }
Keluaran konsol:
Параметр сиденья: диаметр подседельного штыря = 40
Perhatian:variabel baru dideklarasikan dengan pengubah yang paling ketat -
private
. Dan kelas dalam masih memiliki akses! -
Objek kelas dalam tidak dapat dibuat dalam metode statis kelas "luar".
Hal ini dijelaskan oleh fitur desain kelas internal. Kelas dalam dapat memiliki konstruktor dengan parameter atau hanya konstruktor default. Namun terlepas dari ini, saat kita membuat objek kelas dalam, referensi ke objek kelas "luar" diam-diam diteruskan ke dalamnya. Bagaimanapun, kehadiran objek semacam itu merupakan prasyarat. Kalau tidak, kita tidak akan bisa membuat objek kelas dalam.
Tetapi jika metode kelas luarnya statis, maka objek kelas luarnya mungkin tidak ada sama sekali! Artinya logika kelas dalam akan rusak. Dalam situasi seperti ini, kompiler akan memunculkan kesalahan:
public static Seat createSeat() { //Bicycle.this cannot be referenced from a static context return new Seat(); }
-
Kelas dalam tidak boleh berisi variabel dan metode statis.
Logikanya di sini sama: metode dan variabel statis bisa ada dan dipanggil meskipun tidak ada objek.
Tapi tanpa objek kelas “luar”, kita tidak akan memiliki akses ke kelas dalam.
Sebuah kontradiksi yang jelas! Oleh karena itu, kehadiran variabel dan metode statis di kelas dalam dilarang.
Kompiler akan memunculkan kesalahan saat mencoba membuatnya:
public class Bicycle { private int weight; public class Seat { //inner class cannot have static declarations public static void getSeatParam() { System.out.println("Seat parameter: seatpost diameter = " + Bicycle.this.seatPostDiameter); } } }
-
Saat membuat objek kelas dalam, pengubah aksesnya memainkan peran penting.
Kelas dalam dapat dilambangkan dengan pengubah akses standar -
public
,private
,protected
danpackage private
.Mengapa ini penting?
Hal ini mempengaruhi di mana dalam program kita dapat membuat instance kelas dalam.
Jika kelas kita
Seat
dideklarasikan sebagaipublic
, kita dapat membuat objeknya di kelas lain mana pun. Satu-satunya persyaratan adalah bahwa objek kelas “eksternal” juga harus ada.Omong-omong, kami sudah melakukannya 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 mengakses kelas dalam
HandleBar
dariMain
.Jika kita mendeklarasikan kelas dalam sebagai
private
, kita hanya akan memiliki akses untuk membuat objek di dalam kelas “luar”.Seat
Kita tidak lagi dapat membuat objek dari luar:private class Seat { //methods } public class Main { public static void main(String[] args) { Bicycle bicycle = new Bicycle("Peugeot", 120, 40); //Bicycle.Seat has a private access in 'Bicycle' Bicycle.Seat seat = bicycle.new Seat(); } }
Anda mungkin sudah memahami logikanya :)
-
Pengubah akses untuk kelas dalam bekerja sama seperti variabel reguler.
Pengubah
protected
menyediakan akses ke variabel kelas di kelas turunannya dan di kelas yang ada dalam paket yang sama.Hal yang sama
protected
berlaku untuk kelas dalam. Objekprotected
kelas dalam dapat dibuat:- di dalam kelas "luar";
- di kelas keturunannya;
- di kelas-kelas yang berada dalam paket yang sama.
Jika kelas dalam tidak memiliki pengubah akses (
package private
), objek kelas dalam dapat dibuat- di dalam kelas "luar";
- di kelas-kelas yang berada dalam paket yang sama.
Anda sudah lama mengenal modifikator, jadi tidak akan ada masalah di sini.
GO TO FULL VERSION