Pages

Rabu, 17 Oktober 2007

Penggunaan Kelas Dalam Java

  1. Kelas
  2. Deklarasi Kelas
  3. Konstruktor
  4. Deklarasi Kelas
  5. Kelas Bersarang
  6. Kelas Anonim
  7. Kelas Abstrak
  8. Polimorfisme

Tables

  1. Diagram komponen deklarasi kelas

Kode

  1. Contoh kode kelas sederhana


Oleh Ari Hermawan

Tutorial kali ini akan membahas bagaimana menciptakan dan mengelola kelas dan pewarisan dalam bahasa Java. Pembahasan mengenai kelas akan membahas juga tentang konstruktor yang berfungsi sebagai sarana menciptakan objek dari suatu kelas dan tentang metode yang merupakan implementasi behaviour dari suatu kelas. Selain itu dibahas juga beberapa jenis kelas khusus seperti kelas bersarang dan kelas anonim. Anda diharapkan telah menguasai konsep pemrograman berorientasi objek yang telah dibahas dalam tutorial sebelumnya.

Kelas

Kelas memiliki peran penting dalam paradigma pemrograman berorientasi objek. Kelas bagaikan sebuah pabrik yang siap memproduksi objek-objek yang kita butuhkan. Untuk dapat menciptakan sebuah objek, kita harus menciptakan kelasnya. Kelas inilah yang dalam runtime program akan menciptakan objek yang inginkan. Singkatnya kelas adalah cetak biru bagi objek yang ingin kita ciptakan.

Perlu diperhatikan bahwa umumnya tidak ada batasan jumlah objek yang dapat diciptakan melalui sebuah kelas. Namun terkadang ada kelas-kelas yang memang dirancang untuk menciptakan tidak lebih dari satu objek.

Objek-objek yang tercipta dari sebuah kelas disebut instans dari kelas tersebut. Instans ini akan mempunyai variabel dan metode yang disebut variabel instans dan metode instans. Namun ada juga variabel kelas yang berlaku bagi kelas itu sendiri sehingga akan berlaku juga untuk semua instans dari kelas tersebut.

Di Listing 1 Anda dapat melihat kode contoh kelas sederhana.

Deklarasi Kelas

Pendeklarasian kelas dapat dimulai dengan pernyataan package. Pernyataan seperti baris pertama dari Listing 1 berarti kelas tersebut adalah bagian dari package com.arih. Hirarki package di sini secara konseptual sama dengan konsep pohon, di mana ada node akar dan bercabang terus oleh node anak. Pernyataan ini tidak harus ada dalam setiap kode program kelas. Hanya bila program Anda memiliki banyak kelas dan ingin disusun menurut hirarki tertentu barulah Anda perlu meletakkan pernyataan seperti ini. Biasanya hirarki package mengikuti hirarki domain vendor. Dalam kasus ini, arih.com—nama situs saya.

Setelah pernyataan package, kita dapat meletakkan baris-baris pernyataan import. Pernyataan import digunakan untuk mendaftarkan nama lengkap dari kelas-kelas yang kita impor agar di dalam kelas ini nantinya kita tidak lagi perlu menuliskan nama lengkap secara hirarkis sebuah kelas. Contohnya di Listing 1 kita meletakkan baris import java.io.*;, artinya semua kelas yang berada di dalam package java.io dapat kita panggil dalam kelas kita langsung dengan nama kelas, tanpa nama package. Jadi bila kita ingin menggunakan kelas java.io.InputStreamReader, kita dapat langsung menuliskan InputStreamReader tanpa mesti membubuhkan java.io di depannya. Dalam kasus tertentu kemudahan ini dapat terganggu bila ada dua kelas dengan nama yang sama namun dari package berbeda yang keduanya kita impor. Akibatnya penggunaan nama kelas tersebut akan menyebabkan ambiguitas. Pemecahannya adalah dengan menggunakan nama lengkap, atau minimal nama package yang berbeda untuk kedua kelas tersebut.

Baris-baris pernyataan impor ini sebenarnya hanya berfungsi sebagai pembantu agar penulisan kode program lebih mudah dan lebih singkat. Jadi hal ini tidak wajib dilakukan. Selama Anda merasa senang menulis nama lengkap suatu kelas yang biasanya cukup panjang, silahkan tidak menggunakan fasilitas impor. Kalaupun Anda menggunakan fasilitas ini, biasakanlah untuk tetap mengetahui nama lengkap dari kelas-kelas yang Anda gunakan. Dengan begitu Anda tidak akan kesusahan bila ingin melihat dokumentasi API Java untuk kelas tersebut.

Konstruktor

Kita sudah mengetahui bahwa kelas adalah alat untuk menciptakan objek. Sekarang yang menjadi pertanyaan adalah bagaimana cara menciptakan objek menggunakan sebuah kelas. Jawabannya adalah dengan menggunakan sebuah konstruktor.

Apakah sebuah konstruktor itu? Konstruktor adalah bagian dari definisi suatu kelas yang berfungsi menciptakan instans dari kelas tersebut. Konstruktor ini bisa kita buat sendiri, atau bila kita tidak mendefinisikannya, maka kompiler Java akan membuatkan konstruktor default untuk kelas tersebut pada saat kompilasi. Yang perlu diperhatikan adalah bahwa suatu konstrukor tidak termasuk anggota suatu kelas seperti metode dan variabel dan bahwa konstruktor bisa dibuat lebih dari satu.

Bentuk konstruktor sendiri mirip dengan sebuah metode. Beda yang paling mencolok adalah nama sebuah konstruktor harus sama dengan nama kelas tersebut dan konstruktor tidak memiliki definisi return type seperti sebuah metode. Untuk jelasnya Anda bisa lihat kembali Listing 1, di mana terdapat dua buah konstruktor. Yang satu adalah konstruktor default dan yang lain adalah konstruktor dengan sebuah parameter bertipe int.

Adanya dua buah konstruktor ini termasuk sifat polimorfisme dalam pemrograman berorientasi objek. Sifat ini dapat berlaku bagi konstruktor dan juga metode. Lebih jauh mengenai polimorfisme akan dijelaskan lebih jauh di akhir tutorial ini.

Secara singkat, konstruktor adalah perintah yang akan dilaksanakan saat ada instruksi untuk menciptakan sebuah instans dari kelas tersebut. Bisa saja konstruktor tersebut tidak melakukan apa-apa, yaitu bila konstruktor tersebut kosong. Berikut adalah contoh-contoh penciptaan suatu kelas dengan berbagai jenis konstruktor.

SuatuKelas kelasContoh = new SuatuKelas();
SuatuKelasLain kelasContoh2 = new SuatuKelasLain("judul");
BufferedReader reader =
new BufferedReader(new InputStreamReader(System.in));
new SuatuKelas().sebuahMetode();

Pada contoh pertama, kita menciptakan sebuah instans dari kelas SuatuKelas dengan memanggil konstruktor tanpa parameter. Bila dalam pendefinisian kelas SuatuKelas sebenarnya tidak ada pendefinisian konstruktor, perintah seperti ini tetap dapat dipakai, karena kompiler Java akan menyisipkan secara otomatis kosntruktor default bila tidak ada definisi konstruktor dalam sebuah kelas. Konstruktor default sendiri sebenarnya tidak melakukan apa-apa dalam proses instansiasi objek, karena tidak berisi perintah apapun.

Pada contoh kedua, kita memanggil sebuah konstruktor yang mengandung argumen berupa sebuah parameter bertipe String. Konstruktor seperti ini menjadi sangat berguna bila dalam proses instansiasi sebuah objek kita ingin memasukkan suatu nilai untuk dapat digunakan oleh instans baru tersebut.

Pada contoh ketiga, kita memanggil konstruktor dengan argumen sebuah parameter bertipe InputStreamReader. Yang menarik dari contoh ini adalah kita memasukkan argumen berupa kelas baru yang anonim sehingga terjadi pemanggilan konstruktor lain di dalam argumen konstruktor semula. Dalam konstruktor yang terakhir kita juga memasukkan argumen berupa sebuah objek InputStream yaitu System.in.

Contoh keempat adalah contoh yang lebih jelas mengenai kelas anonim. Pada contoh ini kita menciptakan sebuah instans dari kelas SuatuKelas namun tidak menyimpan referensi ke instans tersebut, sehingga kita hanya bisa menggunakannya sekali, yaitu langsung pada baris tersebut seperti terlihat pada contoh.

Ada hal yang menarik dan perlu diperhatikan mengenai konstruktor dalam kelas-kelas yang merupakan subkelas. Pada saat kita menginstans sebuah objek dari sebuah subkelas, kompiler tidak hanya memanggil konstruktor subkelas tersebut, melainkan memanggil kosntruktor superkelasnya terlebih dahulu, baru kemudian memanggil konstruktor subkelas tersebut. Penjelasan mengenai hal ini adalah bahwa sebuah subkelas adalah superkelas itu sendiri namun dengan tambahan karakterisasi yang lebih detil. Sehingga untuk menginstans sebuah subkelas, pertama-tama kita menginstansiasi sebuah superkelas, kemudian menerapkan karakterisasi dari subkelas kepada instans baru tersebut.

Deklarasi Kelas

Deklarasi kelas terdiri dari beberapa komponen. Contoh deklarasi kelas adalah seperti pada Listing 1, yaitu public class KelasKita implements InterfaceKita1, InterfaceKita2 extends SuperKelas. Dari semua komponen tersebut, yang harus ada adalah bagian class namakelas, sedang yang lain adalah opsional. Tabel 1 akan menunjukkan diagram komponen deklarasi kelas berikut penjelasan singkat.

Kelas Bersarang

Kelas bersarang adalah deklarasi kelas yang terletak di dalam isi kelas lain. Akibatnya kelas baru ini menjadi anggota dari kelas yang melingkupinya.

Kita dapat menggunakan kelas bersarang untuk menerapkan hubungan antara dua kelas dimana kelas bersarang tersebut hanya ada dalam konteks kelas yang melingkupinya. Contohnya, bila kita membuat kelas Listener untuk event yang khusus oleh sebuah kelas, misalnya tombol atau mouse diklik dalam sebuah kelas yang berupa Applet. Maka kita mendeklarasikan kelas Listener tersebut sebagai anggota dari kelas yang memproduksi event.

Selain contoh sebelumnya, kelas bersarang juga dapat digunakan bila sebuah kelas membutuhkan kelas lain untuk dapat berfungsi. Maka kelas tersebut dideklarasikan sebagai anggota dari kelas yang memiliki kebutuhannya. Misalnya kita ingin membuat kelas yang berupa dialog, dan dialog ini membutuhkan sebuah kelas lain sebagai parent dari dialog ini. Maka kita meletakkan kelas dialog tersebut dalam kelas parentnya.

Kelas Anonim

Kelas anonim adalah kelas yang tidak mempunyai nama. Dalam program artinya kelas ini tidak memiliki referensi yang disimpan di simbol tertentu. Akibatnya kita tidak dapat mengakses kelas tersebut dengan menggunakan cara biasa. Satu-satunya cara mengakses kelas seperti ini adalah langsung pada baris instansiasinya. Contoh kelas seperti ini telah kita lihat dalam contoh mengenai konstruktor.

Kelas anonim dapat kita gunakan bila kita ingin menciptakan sebuah kelas namun hanya butuh menggunakannya sekali dan tidak ingin mengalokasikan memori untuknya karena memang tidak akan digunakan lagi. Kasus seperti ini terjadi misalnya kita ingin menciptakan sebuah kelas baru sebagai argumen untuk sebuah konstruktor atau metode, dimana kita tidak lagi ingin mengakses kelas tersebut secara langsung. Contohnya adalah kasus ketiga dalam contoh mengenai konstruktor. Di sana kita menciptakan sebuah kelas InputStream untuk argumen konstruktor BufferedReader, namun kita tidak ingin menyimpan referensi ke objek InputStream tersebut, karena penggunaannya oleh BufferedReader juga akan berjalan tanpa perintah eksplisit dari program. Jadi sebenarnya referensi ke objek InputStream tersebut disimpan oleh instans BufferedReader, bukan oleh kelas kita.

Kelas Abstrak

Kelas abstrak adalah kelas yang mengandung konsep abstrak sehingga tidak mungkin mempunyai instans. Misalnya suatu kelas abstrak Buah yang mengandung konsep tentang bagian dari tumbuhan yang dapat dimakan. Namun kita tidak dapat menciptakan sebuah instans dari kelas tersebut karena tidak masuk akal menciptakan suatu Buah. Yang mungkin adalah menciptakan instans dari kelas Jeruk, Apel, atau kelas lain yang sudah mengimplementasikan konsep abstrak dari buah.

Kelas abstrak dapat mengandung metode abstrak, yaitu metode yang tidak memiliki implementasi. Dengan begitu, kelas abstrak dapat menentukan bagaimana konsep abstrak tersebut diimplementasikan oleh subkelas yang akan menggunakannya. Kelas abstrak tidak harus memiliki metode abstrak, namun setiap kelas yang memiliki metode abstrak haruslah menjadi kelas abstrak.

Polimorfisme

Polimorfisme secara bahasa dapat diartikan memiliki banyak bentuk. Konsep ini terdapat dalam bahasa pemrograman seperti konstruktor yang memiliki beberapa bentuk. Selain konstruktor, konsep ini juga berlaku bagi metode. Metode atau konstruktor dapat memiliki banyak bentuk dalam arti memiliki nama yang sama namun dengan argumen yang berbeda atau dengan return type yang berbeda. Contoh polimorfisme untuk konstruktor maupun untuk metode dapat Anda lihat pada Listing 1. Disana terdapat konstruktor-konstruktor dengan nama sama namun dengan argumen yang mengandung parameter-parameter yang berbeda. Untuk contoh polimorfisme untuk metode ditunjukkan bahwa terdapat metode dengan nama sama namun memiliki argumen dan return type yang berbeda.

Kegunaan dari polimorfisme adalah agar kita dapat mendefinisikan beberapa konstruktor atau metode dengan karakteristik yang berbeda-beda agar nantinya dapat digunakan untuk kasus-kasus yang berbeda. Misalnya kita ingin menciptakan instans dari kelas KelasKita pada Listing 1 tanpa memberikan nilai apapun, namun terkadang kita ingin memberikan sebuah nilai sebagai parameter untuk digunakan oleh instans dari kelas tersebut, maka kita dapat membuat kelas seperti KelasKita tersebut. Begitu juga halnya dengan metode, sehingga kita dapat membuat metode-metode yang memiliki karakteristik yang khusus.

Polimorfisme sebenarnya dapat dihilangkan dengan medefinisikan sebuah konstruktor atau metode yang dapat menangani semua kasus yang mungkin. Namun hal ini akan menyebabkan program Anda lebih rumit dan sulit dimengerti. Sedangkan polimorfisme yang membantu Anda untuk membuat program yang lebih baik dan mudah juga membawa konsekuensi yaitu proses kompilasi yang lebih rumit, dan penurunan kecepatan eksekusi kelas. Namun hal ini tidak perlu menjadi perhatian Anda kecuali Anda memang ingin mendalami proses kompilasi Java.

Ari Hermawan mahasiswa fakultas Ilmu Komputer UI. Sehari-hari dapat ditemukan di Lab kampus sedang bingung dengan pertanyaan tentang Java dari komunitas Java di Internet. Saat ini sedang berusaha mempromosikan diri sebagai konsultan Java sambil berusaha keras untuk lulus. Ari dapat dihubungi di arih@pokuz.net.

Tidak ada komentar: