Kelas batin

T: Jadi, untuk apa kelas batin itu bagus?

J: Kelas-kelas dalam bersarang di dalam kelas-kelas lain. Kelas normal adalah anggota langsung dari sebuah paket, kelas tingkat atas. Kelas dalam, yang tersedia dengan Java 1.1, hadir dalam empat jenis:

  • Kelas anggota statis
  • Kelas anggota
  • Kelas lokal
  • Kelas anonim

Mari kita lihat satu per satu.

Singkatnya, kelas anggota statis adalah anggota kelas statis. Seperti metode statis lainnya, kelas anggota statis memiliki akses ke semua metode statis induk, atau kelas tingkat atas.

Seperti kelas anggota statis, kelas anggota juga didefinisikan sebagai anggota kelas. Tidak seperti variasi statis, kelas anggota adalah instance khusus dan memiliki akses ke semua metode dan anggota, bahkan thisreferensi induknya .

Kelas lokal dideklarasikan dalam satu blok kode dan hanya terlihat di dalam blok itu, sama seperti variabel metode lainnya.

Terakhir, kelas anonim adalah kelas lokal yang tidak memiliki nama.

Untuk menjawab pertanyaan spesifik Anda, saya akan fokus pada anggota dan kelas dalam anonim karena itulah yang kemungkinan akan Anda temui dan gunakan. Bagi saya, keunggulan kelas dalam dapat dibagi menjadi tiga kategori: keunggulan berorientasi objek, keunggulan organisasi, dan keunggulan panggilan kembali.

Keuntungan berorientasi objek

Menurut pendapat saya yang sederhana, fitur terpenting dari inner class adalah memungkinkan Anda mengubah sesuatu menjadi objek yang biasanya tidak akan Anda ubah menjadi objek. Itu memungkinkan kode Anda menjadi lebih berorientasi objek daripada tanpa kelas dalam.

Mari kita lihat kelas anggota. Karena instance-nya adalah anggota dari instance induknya, ia memiliki akses ke setiap anggota dan metode di induknya. Sekilas, ini mungkin tidak terlihat banyak; kita sudah memiliki akses semacam itu dari dalam metode di kelas induk. Namun, kelas anggota memungkinkan kita untuk mengeluarkan logika dari induk dan mengobyektifkannya. Misalnya, kelas pohon mungkin memiliki metode dan banyak metode pembantu yang melakukan penelusuran atau berjalan di pohon. Dari sudut pandang berorientasi objek, pohon adalah pohon, bukan algoritma pencarian. Namun, Anda memerlukan pengetahuan mendalam tentang struktur data pohon untuk melakukan penelusuran.

Kelas dalam memungkinkan kita untuk menghapus logika itu dan menempatkannya ke dalam kelasnya sendiri. Jadi dari sudut pandang berorientasi objek, kami telah mengambil fungsionalitas dari tempat yang bukan miliknya dan memasukkannya ke dalam kelasnya sendiri. Melalui penggunaan kelas dalam, kami telah berhasil memisahkan algoritma pencarian dari pohon. Sekarang, untuk mengubah algoritma pencarian, kita cukup menukar di kelas baru. Saya bisa melanjutkan, tetapi itu membuka kode kami untuk banyak keuntungan yang diberikan oleh teknik berorientasi objek.

Keuntungan organisasi

Desain berorientasi objek bukanlah urusan semua orang, tetapi untungnya, kelas dalam menyediakan lebih banyak. Dari sudut pandang organisasi, kelas dalam memungkinkan kita untuk mengatur lebih lanjut struktur paket kita melalui penggunaan ruang nama. Alih-alih membuang semuanya ke dalam paket datar, kelas dapat disarangkan lebih lanjut di dalam kelas. Secara eksplisit, tanpa kelas dalam, kami dibatasi pada struktur hierarki berikut:

paket1 kelas 1 kelas 2 ... kelas n ... paket n 

Dengan kelas dalam kita dapat melakukan hal berikut:

paket 1 kelas 1 kelas 2 kelas 1 kelas 2 ... kelas n 

Jika digunakan dengan hati-hati, kelas dalam dapat memberikan hierarki struktural yang lebih sesuai dengan kelas Anda secara alami.

Keuntungan panggilan balik

Kelas anggota dalam dan kelas anonim keduanya menyediakan metode yang nyaman untuk mendefinisikan callback. Contoh paling jelas berkaitan dengan kode GUI. Namun, penerapan callback dapat meluas ke banyak domain.

Kebanyakan GUI Java memiliki beberapa jenis komponen yang memicu actionPerformed()pemanggilan metode. Sayangnya, sebagian besar pengembang hanya menerapkan jendela utama mereka ActionListener. Hasilnya, semua komponen menggunakan actionPerformed()metode yang sama . Untuk mengetahui komponen mana yang melakukan tindakan, biasanya ada tombol raksasa yang jelek dalam actionPerformed()metode.

Berikut adalah contoh implementasi monolitik:

public class SomeGUI extends JFrame mengimplementasikan ActionListener {dilindungi JButton button1; dilindungi tombol JButton2; ... dilindungi tombol JButtonN; public void actionPerformed (ActionEvent e) {if (e.getSource () == button1) {// do something} else if (e.getSource () == button2) {... Anda mendapatkan gambarnya

Setiap kali Anda melihat sakelar atau besar if/ if elseblok, bel alarm yang keras akan mulai berdering di benak Anda. Secara umum, konstruksi seperti itu adalah desain berorientasi objek yang buruk karena perubahan dalam satu bagian kode mungkin memerlukan perubahan yang sesuai dalam pernyataan switch. Kelas anggota dalam dan kelas anonim memungkinkan kita untuk menjauh dari actionPerformed()metode yang dialihkan .

Sebagai gantinya, kita dapat mendefinisikan kelas dalam yang mengimplementasikan ActionListeneruntuk setiap komponen yang ingin kita dengarkan. Itu mungkin menghasilkan banyak kelas batin. Namun, kami dapat menghindari pernyataan sakelar besar dan memiliki bonus tambahan untuk merangkum logika tindakan kami. Selain itu, pendekatan tersebut dapat meningkatkan kinerja. Dalam sakelar di mana terdapat n perbandingan, kita dapat mengharapkan perbandingan n / 2 dalam kasus rata-rata. Kelas dalam memungkinkan kita untuk mengatur korespondensi 1: 1 antara pelaku tindakan dan pendengar tindakan. Dalam GUI yang besar, pengoptimalan seperti itu dapat berdampak besar pada kinerja. Pendekatan anonim mungkin terlihat seperti ini:

public class SomeGUI memperluas JFrame {... deklarasi anggota tombol ... dilindungi void buildGUI () {button1 = new JButton (); tombol2 = JButton baru (); ... button1.addActionListener (new java.awt.event.ActionListener () {public void actionPerformed (java.awt.event.ActionEvent e) {// do something}}); .. ulangi untuk setiap tombol

Menggunakan kelas anggota dalam, program yang sama akan terlihat seperti ini:

kelas publik SomeGUI memperluas JFrame {... deklarasi anggota tombol // definisi kelas dalam kelas Button1Handler mengimplementasikan ActionListener {public void actionPerformed (ActionEvent e) {// melakukan sesuatu}} ... menentukan kelas anggota dalam untuk setiap tombol yang dilindungi void buildGUI () {// inisialisasi tombol button1 = new JButton (); tombol2 = JButton baru (); ... // daftarkan instance pendengar tindakan kelas dalam // untuk setiap tombol button1.addActionListener (new Button1Handler ()); .. ulangi untuk setiap tombol

Karena kelas dalam memiliki akses ke semua yang ada di induk, kita dapat memindahkan logika apa pun yang akan muncul dalam actionPerformed()implementasi monolitik ke kelas dalam.

Saya lebih suka menggunakan kelas anggota sebagai callback. Namun, itu adalah masalah preferensi pribadi. Saya hanya merasa bahwa terlalu banyak kelas anonim mengacaukan kode. Saya juga merasa bahwa kelas anonim bisa menjadi berat jika lebih besar dari satu atau dua baris.

Kekurangan?

Seperti hal lainnya, Anda harus menerima yang baik dengan yang buruk. Kelas batin memiliki kekurangan. Dari sudut pandang pemeliharaan, pengembang Java yang tidak berpengalaman mungkin merasa kelas dalam sulit untuk dipahami. Penggunaan kelas dalam juga akan meningkatkan jumlah kelas dalam kode Anda. Selain itu, dari sudut pandang pengembangan, sebagian besar alat Java kurang mendukung kelas dalam mereka. Sebagai contoh, saya menggunakan VisualAge untuk Java dari IBM untuk pengkodean harian saya. Sementara kelas-kelas dalam akan dikompilasi dalam VisualAge, tidak ada browser atau templat kelas dalam. Sebaliknya, Anda cukup mengetik kelas dalam langsung ke dalam definisi kelas. Sayangnya itu membuat penjelajahan kelas dalam menjadi sulit. Juga sulit untuk mengetik karena Anda kehilangan banyak VisualAge 'bantuan penyelesaian kode s ketika Anda mengetik ke dalam definisi kelas atau menggunakan kelas dalam.

Tony Sintes adalah konsultan senior di ObjectWave, dengan spesialisasi di bidang telekomunikasi. Sintes, programmer Java 1.1 bersertifikat Sun dan pengembang Java 2, telah bekerja dengan Java sejak 1997.

Pelajari lebih lanjut tentang topik ini

  • "Spesifikasi Kelas Dalam", dari Sun, memberikan gambaran mendalam tentang kelas-kelas dalam

    //java.sun.com/products/jdk/1.1/docs/guide/innerclasses/spec/innerclasses.doc.html

Cerita ini, "Kelas batin", awalnya diterbitkan oleh JavaWorld.