Banyak orang mungkin belum familiar dengan inner class Java. Faktanya, konsep serupa ada di C++, yaitu perbedaan dan hubungan antara keduanya akan dibandingkan di bawah. Di permukaan, kelas dalam hanyalah kelas lain yang didefinisikan di dalam kelas (seperti yang akan Anda lihat di bawah, kelas dalam dapat didefinisikan di banyak tempat), namun kenyataannya tidak sesederhana itu berlebihan. Kegunaannya mungkin tidak begitu jelas bagi pemula, tetapi dengan pemahaman yang lebih mendalam, Anda akan menemukan bahwa para desainer Java memang memiliki niat baik di kelas internal. Belajar menggunakan kelas dalam adalah bagian dari penguasaan pemrograman Java tingkat lanjut, yang memungkinkan Anda merancang struktur program dengan lebih elegan. Mari kita perkenalkan dari aspek berikut:
pertemuan pertama
Copy kode kodenya sebagai berikut:
antarmuka publik Isi {
int nilai();
}
antarmuka publik Tujuan {
String readLabel();
}
Barang kelas umum {
kelas privat Konten mengimplementasikan Konten {
int pribadi i = 11;
nilai int publik() {
kembalikan saya;
}
}
kelas yang dilindungi GDestination mengimplementasikan Destination {
label String pribadi;
GDestinasi pribadi(String di manaKe) {
label = kemana Ke;
}
String publik readLabel() {
label pengembalian;
}
}
Tujuan Umum tujuan(String s) {
kembalikan GDestinasi baru;
}
publik Konten lanjutan() {
kembalikan Konten baru();
}
}
kelas Barang Uji Coba {
public static void main(String[] args) {
Barang p = Barang baru();
Isi c = p.lanjut();
Tujuan d = p.dest("Beijing");
}
}
Dalam contoh ini, kelas Konten dan GDestinasi didefinisikan di dalam kelas Barang, dan masing-masing memiliki pengubah yang dilindungi dan pribadi untuk mengontrol tingkat akses. Konten mewakili konten Barang, dan GDestination mewakili tujuan Barang. Mereka mengimplementasikan dua antarmuka Konten dan Tujuan masing-masing. Dalam metode utama berikut, Anda langsung menggunakan Contents c dan Destination d untuk mengoperasikannya. Anda bahkan tidak melihat nama dari dua kelas internal ini! Dengan cara ini, manfaat pertama dari kelas dalam adalah untuk menyembunyikan operasi yang Anda tidak ingin orang lain mengetahuinya, yaitu enkapsulasi.
Pada saat yang sama, kami juga menemukan cara pertama untuk mengeluarkan objek kelas dalam di luar cakupan kelas luar, yaitu dengan membuat dan mengembalikannya menggunakan metode kelas luarnya. Metode cont() dan dest() pada contoh di atas melakukan hal ini. Jadi apakah ada cara lain?
Tentu saja ada,
format sintaksnya adalah sebagai berikut:
outerObject=new outerClass(Parameter Konstruktor);
outerClass.innerClass innerObject=outerObject.new InnerClass(Parameter Konstruktor);
Perhatikan bahwa saat membuat objek kelas dalam non-statis, Anda harus terlebih dahulu membuat objek kelas luar yang sesuai. Adapun alasannya, ini mengarah ke topik berikutnya. Objek kelas dalam non-statis memiliki referensi ke objek kelas luarnya.
Ubah sedikit contoh sebelumnya:
Copy kode kodenya sebagai berikut:
Barang kelas umum {
nilaiRate int pribadi = 2;
kelas privat Konten mengimplementasikan Konten {
int pribadi i = 11 * NilaiNilai;
nilai int publik() {
kembalikan saya;
}
}
kelas yang dilindungi GDestination mengimplementasikan Destination {
label String pribadi;
GDestinasi pribadi(String di manaKe) {
label = kemana Ke;
}
String publik readLabel() {
label pengembalian;
}
}
Tujuan Umum tujuan(String s) {
kembalikan GDestinasi baru;
}
publik Konten lanjutan() {
kembalikan Konten baru();
}
}
Di sini kita menambahkan variabel anggota privat valueRate ke kelas Barang, yang berarti koefisien nilai barang. Ini dikalikan dengan nilai tersebut ketika metode value() dari kelas internal Content menghitung nilainya. Kami menemukan bahwa value() dapat mengakses valueRate, yang merupakan manfaat kedua dari kelas dalam. Objek kelas dalam dapat mengakses konten objek kelas luar yang membuatnya, bahkan variabel pribadi! Ini adalah fitur yang sangat berguna yang memberi kita lebih banyak ide dan jalan pintas saat mendesain. Untuk mencapai fungsi ini, objek kelas dalam harus memiliki referensi ke objek kelas luar. Ketika kompiler Java membuat objek kelas dalam, ia secara implisit meneruskan referensi ke objek kelas luarnya dan menyimpannya. Hal ini memungkinkan objek kelas dalam untuk selalu mengakses objek kelas luarnya, dan ini juga mengapa untuk membuat objek kelas dalam di luar cakupan kelas luar, Anda harus membuat objek kelas luarnya terlebih dahulu.
Beberapa orang mungkin bertanya, apa yang harus saya lakukan jika variabel anggota di kelas dalam memiliki nama yang sama dengan variabel anggota di kelas luar, yaitu variabel anggota kelas luar dengan nama yang sama diblokir? Tidak apa-apa. Java menggunakan format berikut untuk mengekspresikan referensi ke kelas eksternal:
kelas luar.ini
Dengan itu, kami tidak takut dengan situasi yang melindungi ini.
kelas dalam statis
Seperti kelas biasa, kelas dalam juga bisa bersifat statis. Namun, dibandingkan dengan kelas dalam non-statis, perbedaannya adalah kelas dalam statis tidak memiliki referensi eksternal. Ini sebenarnya sangat mirip dengan kelas bersarang di C++. Perbedaan terbesar antara kelas internal Java dan kelas bersarang C++ adalah apakah ada referensi ke luar. Tentu saja, dari sudut pandang desain dan beberapa detailnya, ada perbedaan.
Selain itu, di kelas dalam non-statis mana pun, tidak boleh ada data statis, metode statis, atau kelas dalam statis lainnya (kelas dalam dapat disarangkan lebih dari satu tingkat). Tapi Anda bisa mendapatkan semua ini di kelas dalam statis. Ini bisa dianggap sebagai perbedaan kedua antara keduanya.
kelas dalam lokal
Ya, kelas dalam Java juga bisa bersifat lokal, mereka dapat didefinisikan dalam suatu metode atau bahkan blok kode.
Copy kode kodenya sebagai berikut:
Barang kelas umum1 {
Tujuan Umum tujuan(String s) {
kelas GDestination mengimplementasikan Tujuan {
label String pribadi;
GDestinasi pribadi(String di manaKe) {
label = kemana Ke;
}
String publik readLabel() {
label pengembalian;
}
}
kembalikan GDestinasi baru;
}
public static void main(String[] args) {
Barang1 g = Barang baru1();
Tujuan d = g.dest("Beijing");
}
}
Di atas adalah salah satu contohnya. Dalam metode tujuan, kita mendefinisikan kelas dalam, dan akhirnya metode ini mengembalikan objek kelas dalam ini. Jika kita hanya perlu membuat objek kelas dalam dan membuatnya ke luar, kita bisa melakukan ini. Tentu saja, kelas dalam yang ditentukan dalam metode dapat mendiversifikasi desain, dan penggunaannya tidak terbatas pada hal ini.
Berikut ini contoh yang lebih aneh lagi:
Copy kode kodenya sebagai berikut:
Barang kelas umum2 {
private void internalTracking(boolean b) {
jika (b) {
Slip Pelacakan kelas {
id String pribadi;
Slip Pelacakan(String s) {
tanda pengenal = s;
}
String getSlip() {
mengembalikan identitas;
}
}
TrackingSlip ts = TrackingSlip baru("slip");
String s = ts.getSlip();
}
}
jalur kekosongan publik() {
Pelacakan internal(benar);
}
public static void main(String[] args) {
Barang2 g = Barang2 baru();
g.track();
}
}
Anda tidak dapat membuat objek kelas dalam ini di luar if, karena objek tersebut melampaui cakupannya. Namun, selama kompilasi, kelas internal TrackingSlip dikompilasi bersamaan dengan kelas lain, hanya saja kelas tersebut memiliki cakupannya sendiri dan tidak valid di luar cakupan ini. Selain itu, tidak ada bedanya dengan kelas internal lainnya.
kelas dalam anonim
Aturan sintaksis kelas dalam anonim Java mungkin tampak agak aneh, tetapi seperti array anonim, ketika Anda hanya perlu membuat objek suatu kelas dan tidak memerlukan namanya, menggunakan kelas dalam dapat membuat kode terlihat ringkas dan jelas. Aturan sintaksisnya adalah sebagai berikut:
nama antarmuka baru(){......}; atau nama superkelas baru(){......};
Mari lanjutkan dengan contoh di bawah ini:
Copy kode kodenya sebagai berikut:
Barang kelas umum3 {
publik Konten lanjutan() {
kembalikan Konten baru() {
pribadi int i = 11;
nilai int publik() {
kembalikan saya;
}
};
}
}
Metode cont() di sini menggunakan kelas dalam anonim untuk secara langsung mengembalikan objek kelas yang mengimplementasikan antarmuka Contents, yang memang terlihat sangat sederhana.
Dalam adaptor anonim untuk pemrosesan peristiwa Java, kelas dalam anonim banyak digunakan. Misalnya ketika Anda ingin menutup jendela, tambahkan kode ini:
Copy kode kodenya sebagai berikut:
frame.addWindowListener(WindowAdapter baru(){
penutupan jendela public void(WindowEvent e){
Sistem.keluar(0);
}
});
Satu hal yang perlu diperhatikan adalah karena kelas dalam anonim tidak memiliki nama, maka ia tidak memiliki konstruktor (tetapi jika kelas dalam anonim mewarisi kelas induk yang hanya berisi konstruktor berparameter, ia harus membawa parameter ini saat membuatnya, dan Gunakan super kata kunci untuk memanggil konten yang sesuai selama proses implementasi). Jika Anda ingin menginisialisasi variabel anggotanya, ada beberapa metode:
Jika berada dalam kelas dalam suatu metode anonim, Anda dapat menggunakan metode ini untuk meneruskan parameter yang Anda inginkan, namun ingat, parameter ini harus dinyatakan final.
Ubah kelas dalam anonim menjadi kelas dalam lokal bernama sehingga dapat memiliki konstruktor.
Gunakan blok inisialisasi di kelas dalam anonim ini.
Mengapa Anda membutuhkan kelas batin?
Apa manfaat kelas dalam java? Mengapa Anda membutuhkan kelas batin?
Pertama, mari kita ambil contoh sederhana. Jika Anda ingin mengimplementasikan sebuah antarmuka, tetapi metode dalam antarmuka ini memiliki nama dan parameter yang sama dengan metode di kelas yang Anda buat, apa yang harus Anda lakukan? Saat ini, Anda dapat membangun kelas dalam untuk mengimplementasikan antarmuka ini. Karena kelas dalam dapat diakses oleh semua yang ada di kelas luar, hal ini akan menyelesaikan semua fungsionalitas yang Anda miliki jika Anda mengimplementasikan antarmuka secara langsung.
Namun Anda mungkin ingin bertanya, bukankah cukup mengubah metode saja?
Memang benar, menggunakan ini sebagai alasan untuk merancang kelas internal sungguh tidak meyakinkan.
Alasan sebenarnya adalah ini. Bersama-sama, kelas internal dan antarmuka di Java dapat memecahkan masalah yang sering dikeluhkan oleh programmer C++ di Java tanpa pewarisan ganda. Faktanya, pewarisan berganda C++ sangat rumit untuk dirancang, dan Java dapat mencapai efek pewarisan berganda dengan sangat baik melalui kelas internal dan antarmuka.