5. Pengenalan Kelas dan Objek
Bab ini akan
mengenalkan kelas. Kelas merupakan fondasi bagi C# karena mendefinisikan sifat
sebuah objek. Di samping itu, kelas juga membentuk basis untuk pemrograman
berorientasi objek. Di dalam suatu kelas didefinisikan kode dan data. Karena
kelas dan objek merupakan hal fundamental bagi C#, maka akan dibahas secara
panjang lebar, pada beberapa bab dalam buku ini. Bab ini memulai diskusi
tentang beberapa fitur utama kelas.
Hal
Fundamental Pada Kelas
Anda telah
menggunakan beberapa kelas di awal buku ini. Tentu saja, hanya beberapa kelas
sederhan yang digunakan, dan belum mengeksploitasi semua fitur yang dimiliki
sebuah kelas.
Pada bab ini
akan dibahas beberapa fitur utama kelas. Kelas merupakan sebuah template yang
mendefinisikan format suatu objek. Kelas menspesifikasi data dan kode yang akan
dioperasikan terhadap data tersebut. C# menggunakan spesifikasi kelas untuk
membentuk objek. Objek adalah instans dari suatu kelas. Jadi, kelas secara
esensial adalah rancangan yang menspesifikasi bagaimana membangun sebuah objek.
Adalah hal penting bagi Anda untuk memahami ini: Kelas adalah sebuah abstraksi
logis. Representasi fisik dari sebuah kelas tidak ada di dalam memori jika
objek dari kelas tersebut tidak diciptakan.
Format
Umum Kelas
Ketika Anda
mendefinisikan suatu kelas, Anda mendeklarasikan data yang dimuatnya dan kode
yang dioperasikan pada data tersebut. Kelas sederhana bisa saja memuat hanya
kode atau hanya data saja, tetapi hampir semua kelas di dunia aplikasi memuat
keduanya.
Dalam
peristilahan umum, data dimuat dalam anggota data yang didefinisikan kelas, dan
kode dimuat di dalam anggota fungsi. Sebagai contoh, anggota data (yang juga
dikenal dengan bidang) mencakung variabel instand dan variabel statik. Fungsi
anggota mencakup metode, konstruktor, destruktor, indekser, event, operator,
dan properti. Untuk saat ini, diskusi akan dibatasi pada elemen-elemen
esensial: variabel instans dan metode. Berikutnya pada bab ini, akan
didiskusikan mengenai konstruktor dan destruktor. Yang lain akan dibahas pada
beberapa bab selanjutnya.
Sebuah kelas
diciptakan menggunakan katakunci class.
Berikut adalah bentuk umum dari sebuah definisi class sederhana yang hanya memuat variabel instans dan metode:
class namakelas {
//
mendeklarasikan variabel instans
akses tipe
var1;
akses tipe
var2;
// ...
akses tipe varN;
//
mendeklarasikan metode
akses
tipe-nilaibalik metode1(parameter-parameter) {
// tubuh metode
}
akses tipe-nilaibalik
metode2(parameter-parameter) {
// tubuh metode
}
//...
akses tipe-nilaibalik
metodeN(parameter-parameter) {
// tubuh metode
}
}
Perhatikan bahwa
setiap deklarasi variabel metode diawali dengan akses. Di sini, akses adalah sebuah penspesifikasi akses,
seperti public, yang menspesifikasi bagaimana anggota dapa diakses. Seperti
disebutkan pada Bab 1, anggota kelas dapat privat bagi sebuah kelas atau umum
bagi lainnya. Penspesifikasi akses menentukan tipe akses yang diijinkan.
Penspesifikasi akses bersifat opsional, dan jika tidak diberikan, maka anggoa
bersifat privat bagi kelas tersebut. Anggota dengan akses privat hanya dapat
dipakai oleh sesama anggota di dalam kelas. Sebagai contoh pada bab ini, semua
anggota (kecuali untuk metode Main())dispesifikasi
sebagai public, yang berarti bahwa
semua anggota tersebut dapat diakses oleh kode lain, bahkan oleh kode yang
didefinisikan di luar kelas tersebut. Penspesifikasi akses akan dibahas pada
Bab 7.
Sampai titik
ini, kelas yang telah digunakan hanya mempunyai satu metode: Main(). Namun, metode Main() hanya diperlukan jika kelas
tersebut merupakan titik awal program Anda.
Mendefinisikan
Kelas
Untuk
mengilustrasikan kelas, akan dikembangkan sebuah kelas yang mencakup informasi
mengenai bangunan, seperti rumah, kedai, kantor, dan lainnya. Kelas ini disebut
dengan Bangunan, dan menyimpan tiga
item informasi tentang sebuah bangungan: jumlah lantai, luas bangunan, dan
jumlah penghuni.
Versi pertama
dari Bangunan ditunjukkan di sini.
Kelas ini mendefinisikan tiga variabel instans: Lantai, Luas, dan Penghuni. Perhatikan bahwa Bangunan tidak memuat sembarang metode.
Jadi, hanya memuat data. (Nanti akan ditambahkan metode pada kelas tersebut).
class Bangunan
{
public int Lantai; // jumlah lantai
public int Luas; // luas bangunan
public int Penghuni; // jumlah
penghuni
}
Variabel instans
yang didefinisikan oleh Bangunan
mengilustrasikan cara bagaimana variabel instans dideklarasikan secara umum.
Bentuk umum pendeklarasian sebuah variabel instans ditunjukkan di sini:
akses tipe nama-var;
Di sini, akses menspesifikasi
akses; tipe menspesifikasi tipe variabel; dan nama-var menspesifikasi
nama variabel. Jadi, di samping penspesifikasi akses, Anda mendeklarasikan
variabel instans seperti layaknya Anda mendeklarasikan variabel lokal. Untuk
Bangunan, variabel instans diawali dengan pemodifikasi akses public. Seperti yang telah dijelaskan,
ini membolehkannya untuk diakses oleh kode di luara Bangunan.
Definisi class menciptakan sebuah tipe data
baru. Pada kasus ini, tipe data baru dinamakan Bangunan. Anda dapat menggunakan nama ini untuk mendeklarasikan
objek bertipe Bangunan. Ingat bahwa
deklarasi class hanya merupakan
sebuah deskripsi tipe; ia tidak menciptakan objek aktual. Jadi, kode sebelumnya
tidak menyebabkan penciptaan objek bertipe Bangunan.
Untuk menciptakan sebuah objek Bangunan,
Anda bisa menggunakan statemen seperti ini:
Bangunan rumah = new
Bangunan(); // menciptakan sebuah objek
bertipe Bangunan
Setelah statemen
ini dieksekusi, rumah akan menjadi instans dari Bangunan. Jadi, ia akan memiliki realitas fisik. Untuk sementara
ini, Anda tak perlu khawatir tentang detil statemen ini.
Setiap kali Anda
menciptakan instans dari sebuah kelas, Anda menciptakan sebuah objek yang
memuat salinan dari setiap variabel instans yang didefinisikan oleh kelas
tersebut. Jadi, setiap objek Bangunan
akan memuat salinan sendiri dari variabel-variabel instans Lantai, Luas, dan Penghuni. Untuk mengakses ketiga
variabel tersebut, Anda dapat memakai operator akses, yang berupa sebuah titik.
Operator ini dikenal juga dengan operator dot. Operator dot menghubungkan nama
objek dengan nama anggota. Bentuk umum atas operator dot ditunjukkan di sini:
objek.anggota
Jadi, objek dispesifikasi
di sisi kiri, dan anggota ditempatkan di sebelah kanan operator dot. Sebagai contoh,
untuk menugaskan nilai 2 kepada variabel Lantai
dari objek rumah, digunakan statemen
berikut:
rumah.Lantai = 2;
Secara umum,
Anda dapat menggunakan operator dot untuk mengakses variabel instans dan
metode. Berikut adalah sebuah program utuh yang menggunakan kelas Bangunan:
// Sebuah program yang
menggunakan kelas Bangunan.
using System;
class Bangunan
{
public
int Lantai; // jumlah lantai
public
int Luas; // luas bangunan
public
int Penghuni; // jumlah penghuni
}
// kelas ini mendeklarasikan
sebuah objek bertipe Bangunan.
class DemoBangunan
{
static void Main()
{
Bangunan rumah = new Bangunan(); // menciptakan sebuah objek Bangunan
int
luasPO; // luas per orang
// Menugaskan nilai kepada bidang dalam
rumah.
rumah.Penghuni = 4;
rumah.Luas = 2500;
rumah.Lantai = 2;
// Menghitung luas per orang.
luasPO = rumah.Luas / rumah.Penghuni;
Console.WriteLine("rumah mempunyai:\n " +
rumah.Lantai + "
lantai\n " +
rumah.Penghuni +
" penghuni\n " +
rumah.Luas + " luas bangunan\n " +
luasPO + " luas per orang");
}
}
Program ini
memuat dua kelas: Bangunan dan DemoBangunan. Di dalam DemoBangunan, metode Main() menciptakan sebuah instans dari Bangunan, yang dinamakan rumah. Kemudian kode di dalam Main() mengakses beberapa variabel
instans yang berkaitan dengan rumah,
menugaskan nilai kepadanya, dan menggunakannya. Penting untuk memahami bahwa Bangunan dan DemoBangunan adalah dua kelas terpisah. Satu-satunya hubungan
keduanya adalah bahwa satu kelas menciptakan instans dari kelas lainnya.
Meskipun keduanya merupakan kelas terpisah, kode di dalam DemoBangunan dapat mengakses anggota dari Bangunan karena anggota tersebut dideklaraiskan public. Jika tidak diberikan
penspesifikasi akses public, maka
akses terhadap anggota tersebut hanya terbatas di dalam kelas Bangunan, dan kelas DemoBangunan tidak akan bisa
mengaksesnya.
Program tersebut
menghasilkan keluaran berikut:
rumah mempunyai:
2 lantai
4 penghuni
2500 luas bangunan
625 luas per orang
Setiap objek
memiliki salinan sendiri atas variabel instans yang didefinisikan kelasnya.
Jadi, isi variabel di dalam satu objek bisa berbeda dari isi variabel di dalam
objek lain. Tidak ada hubungan antara dua objek kecuali fakta bahwa keduanya
merupakan objek bertipe sama. Sebagai contoh, dua objek Bangunan, masing-masing memiliki salinan sendiri dari Lantai, Luas, dan Penghuni, dan
isi dari ketiga variabel instans tersebut bisa berbeda di dalam dua objek.
Program berikut mendemonstrasikan fakta ini:
// Program ini menciptakan
dua objek Bangunan.
using System;
class Bangunan {
public int Lantai; // jumlah lantai
public int Luas; // luas bangunan
public int Penghuni; // jumlah penghuni
}
// kelas ini mendeklarasikan
dua objek bertipe Bangunan.
class DemoBangunan {
static
void Main() {
Bangunan rumah = new Bangunan();
Bangunan kantor = new Bangunan();
int
luasPO; // luas per orang
// menugaskan nilai ke bidang dalam rumah.
rumah.Penghuni = 4;
rumah.Luas = 2500;
rumah.Lantai = 2;
// menugaskan nilai ke bidang dalam kantor.
kantor.Penghuni = 25;
kantor.Luas = 4200;
kantor.Lantai = 3;
// menghitung luas per orang dalam rumah.
luasPO = rumah.Luas / rumah.Penghuni;
Console.WriteLine("rumah mempunyai:\n " +
rumah.Lantai + " lantai\n " +
rumah.Penghuni + " penghuni\n " +
rumah.Luas + " luas bangunan\n " +
luasPO + " luas per orang");
Console.WriteLine();
// menghitung luas per orang dalam kantor.
luasPO = kantor.Luas / kantor.Penghuni;
Console.WriteLine("kantor mempunyai:\n " +
kantor.Lantai + " lantai\n " +
kantor.Penghuni + " penghuni\n " +
kantor.Luas + " luas bangunan\n " +
luasPO + " luas per orang");
}
}
Program ini
menghasilkan keluaran berikut:
rumah mempunyai:
2 lantai
4 penghuni
2500 luas bangunan
625 luas per orang
kantor mempunyai:
3 lantai
25 penghuni
4200 luas bangunan
168 luas per orang
Seperti yang
bisa Anda lihat, data rumah sama
sekali terpisah dari data yang dimuat kantor.
Gambar 5.1 mengilustrasikan situasi ini.
Gambar 5.1 Variabel instans suatu objek berbeda dengan variabel instans
objek lain
Bagaimana
Objek Diciptakan
Pada program
sebelumnya, baris berikut dipakai untuk mendeklarasikan sebuah objek bertipe Bangunan:
Bangunan rumah = new
Bangunan();
Deklarasi ini
melakukan tiga fungsi: Pertama, ia mendeklarasikan sebuah variabel bernama rumah bertipe Bangunan. Variabel ini sendiri bukan sebuah objek, tetapi hanyalah
sebuah variabel yang merujuk ke sebuah objek. Kedua, deklarasi ini menciptakan
salinan fisik dari objek. Ini dilakukan menggunakan operator new. Terakhir, deklarasi ini menugaskan
sebuah referensi yang menunjuk ke objek kepada rumah. Jadi, setelah baris ini dieksekusi, rumah akan menunjuk ke sebuah objek bertipe Bangunan.
Operator new secara dinamis mengalokasikan
memori untuk sebuah objek dan menghasilkan nilai balik berupa suatu referensi
yang menunjuk ke objek tersebut. Referensi ini kemudian disimpan di dalam
variabel. Jadi, dalam C#, semua objek kelas dialokasikan secara dinamis.
Seperti yang
Anda harapkan, adalah hal yang memungkinkan untuk memisahkan deklarasi atas
rumah dari objek yang akan ditunjuk, seperti ditunjukkan di sini:
Bangunan rumah; //
deklarasi referensi ke objek
rumah = new
Bangunan(); // mengalokasikan sebuah
objek Bangunan
Baris pertama
mendeklarasikan rumah sebagai sebuah
referensi yang menunjuk ke suatu objek bertipe Bangunan. Jadi, rumah
adalah sebuah variabel yang menunjuk ke suatu objek, bukan merupakan objek itu
sendiri. Baris berikutnya menciptakan sebuah objek Bangunan baru dan menugaskan referensi yang menunjuk ke objek
tersebut kepada rumah. Sekarang, rumah terhubung dengan sebuah objek.
Fakta bahwa
objek kelas diakses melalui referensi menjelaskan mengapa kelas disebut dengan
tipe referensi. Perbedaan utama antara tipe nilai dan tipe referensi
adalah apa yang dimaksud dengan tiap
tipe. Untuk variabel bertipe nilai, variabel tersebut memuat nilai. Sebagai
contoh, diberikan
int x;
x = 10;
x memuat nilai 10 karena x
merupakan variabel bertipe int, yang
bertipe nilai. Namun, dalam kasus
Bangunan rumah = new
Bangunan();
rumah tidak memuat objek, tetapi memuat sebuah referensi yang
menunjuk ke objek Bangunan.
Variabel
Referensi dan Penugasan
Dalam operasi
penugasan, variabel referensi berperan berbeda dari variabel bertipe nilai,
seperti int. Ketika Anda menugaskan
satu variabel bertipe nilai kepada variabel lain, situasinya menjadi sederhana.
Variabel di sisi kiri operator penugasan menerima salinan nilai dari variabel
di sisi kanan operator. Ketika Anda menugaskan satu objek bertipe referensi
kepada variabel bertipe referensi lain, situasi menjadi sedikit lebih kompleks
karena penugasan menyebabkan variabel referensi di sisi kiri operator
penugasan menunjuk ke objek yang
ditunjuk oleh variabel referensi di sisi kanan operator penugasan. Objek itu
sendiri tidak disalin. Sebagai contoh, perhatikan fragmen berikut:
Bangunan rumah1 = new
Bangunan();
Bangunan rumah2 = rumah1;
Pada pandangan
pertama, adalah hal mudah untuk berpikir bahwa rumah1 dan rumah2
menunjuk ke dua objek terpisah, tetapi pemikiran ini menyesatkan. Kenyataannya
adalah bahwa rumah1 dan rumah2 keduanya menunjuk ke objek yang
sama. Penugasan rumah1 kepada rumah2 hanya membuat rumah2 menunjuk ke objek yang ditunjuk
oleh rumah1. Setelah penugasan
rumah1.Luas = 2600;
dieksekusi,
kedua statemen WriteLine()
Console.WriteLine(rumah1.Luas);
Console.WriteLine(rumah2.Luas);
menampilkan
nilai sama: 2600.
Meskipun rumah1 dan rumah2 keduanya menunjuk ke objek yang sama. Tetapi, perhatikan
contoh berikut:
Bangunan rumah1 = new
Bangunan();
Bangunan rumah2 = rumah1;
//rumah 1 dan rumah2 menunjuk ke objek yang sama
Bangunan rumah3 = new
Bangunan();
rumah2 = rumah3
//sekarang, rumah2 dan rumah3 menunjuk ke objek yang sama
Setelah runtun
statemen tersebut dieksekusi, rumah2
menunjuk ke objek yang ditunjuk oleh rumah3.
Objek yang ditunjuk oleh rumah1
tidak berubah.
Metode
Seperti yang
telah dijelaskan, variabel instans dan metode merupakan konstituen utama suatu
kelas. Sejauh ini, kelas Bangunan
hanya memuat data, tidak ada metode. Meskipun kelas Bangunan ini dapat diterima, namun kebanyakan kelas memuat metode.
Metode merupakan subrutin yang memanipulasi data yang didefinisikan kelas, dan,
pada banyak kasus, menyediakan akses terhadap data tersebut. Secara umum,
bagian lain dari suatu program akan berinteraksi dengan sebuah kelas melalui
metodenya.
Sebuah metode
memuat satu atau lebih statemen. Dalam kode C# yang ditulis secara profesional,
setiap metode hanya melakukan satu tugas. Setiap metode mempunya nama, dan nama
itu digunakan untuk memanggil metode. Secara umum, Anda dapat menamai metode
menggunakan sembarang pengenal valid yang Anda inginkan. Namun, ingat bahwa
Main() hanya diperuntukkan bagi metode yang mengawali eksekusi program. Di
samping itu, Anda dilarang menggunakan katakunci C# sebagai nama metode.
Ketika menandai
metode di dalam teks, metode memiliki sepasang kurung yang ditempatkan setelah
nama metode. Sebagai contoh, jika nama metode adalah DapatNil, maka ia ditulis DapatNil()
ketika namanya digunakan di dalam kalimat. Notasi ini membantu Anda untuk
membedakan nama variabel dari nama metode dalam buku ini.
Bentuk umum atas
sebuah metode ditampilkan di sini:
akses
tipe-nilaibalik nama (daftar-parameter)
{
// tubuh metode
}
Di sini, akses adalah
pemodifikasi akses yang mengatur bagian program yang dapat memanggil metode
tersebut. Seperti dijelaskan sebelumnya, pemodifikasi akses bersifat opsiona.
Jika tidak diberikan, maka metode bersifat privat bagi kelas. Untuk sekarang, metode
dideklarasikan sebagai public
sehingga dapat dipanggil oleh sembarang kode lain di dalam program. tipe-nilaibalik menspesifikasi
tipe data yang dijadikan nilai balik oleh metode. Tipe nilai balik bisa berupa
sembarang tipe sah, termasuk tipe kelas yang Anda ciptakan. Jika metode tidak
menghasilkan nilai balik, tipenya harus void.
nama menspesifikasi
nama metode, yang dapat berupa pengenal sah. daftar-parameter merupakan
sederet pasangan tipe dan pengenal yang dipisahkan dengan koma. Parameter
adalah variabel yang menerima nilai dari argumen yang dilewatkan kepada metode
ketika metode tersebut dipanggil. Jika metode tidak memiliki parameter, maka
daftar parameternya dibiarkan kosong.
Menambahkan
Metode Dalam Kelas Bangunan
Seperti yang
telah dijelaskan, metode suatu kelas secara umum memanipulasi dan menyediakan
akses terhadap data kelas. Dengan pemahaman ini, Anda perlu mengingat bahwa Main() dalam beberapa contoh sebelumnya
menghitung luas per orang dengan membagi luas bangunan dengan jumlah penghuni. Meskipun
secara teknis perhitungan ini benar, teknik ini bukanlah cara terbaik dalam
menangani perhitungan ini. Perhitungan luas per orang seharusnya ditangai oleh
kelas Bangunan itu sendiri.
Alasannya adalah agar dapat memahami bahwa luas per orang dari suatu bangunan
sangat bergantung pada nilai-nilai di dalam bidang Luas dan Penghuni, yang
terenkapsulasi oleh Bangunan. Jadi,
sangat memungkinkan bagi kelas Bangunan untuk melakukan kalkulasi ini. Di
samping itu, dengan menambahkan perhitungan ini ke dalam Bangunan, Anda mencegah setiap program yang menggunakan Bangunan dari penghitungan secara
manual. Ini mencegah duplikasi kode yang tak penting. Terakhir, dengan
menambahkan sebuah metode untuk menghitung luas per orang ke dalam kelas Bangunan, Anda telah melakukan pemrograman berorientasi
objek dengan mengenkapsulasi kuantitas yang berelasi langsung dengan Bangunan.
Untuk
menambahkan sebuah metode ke dalam Bangunan,
Anda perlu menspesifikasinya di dalam deklarasi Bangunan. Sebagai contoh, versi
Bangunan berikut memuat sebuah metode bernama LuasPerOrang() yang menampilkan luas per orang dari suatu bangunan:
// Program ini menciptakan
dua objek Bangunan.
using System;
class Bangunan {
public
int Lantai; // jumlah lantai
public
int Luas; // luas bangunan
public int Penghuni; // jumlah penghuni
// Menampilkan luas per orang.
public
void LuasPerOrang() {
Console.WriteLine("
" + Luas / Penghuni + " luas
per orang");
}
}
// menggunakan metode
LuasPerOrang().
class DemoBangunan {
static
void Main() {
Bangunan rumah = new Bangunan();
Bangunan kantor = new Bangunan();
int
luasPO; // luas per orang
// menugaskan nilai ke bidang dalam rumah.
rumah.Penghuni = 4;
rumah.Luas = 2500;
rumah.Lantai = 2;
// menugaskan nilai ke bidang dalam kantor.
kantor.Penghuni = 25;
kantor.Luas = 4200;
kantor.Lantai = 3;
Console.WriteLine("rumah mempunyai:\n " +
rumah.Lantai + " lantai\n " +
rumah.Penghuni + " penghuni\n " +
rumah.Luas + " luas bangunan");
rumah.LuasPerOrang();
Console.WriteLine();
Console.WriteLine("kantor mempunyai:\n " +
kantor.Lantai + " lantai\n " +
kantor.Penghuni + " penghuni\n " +
kantor.Luas + " luas bangunan");
kantor.LuasPerOrang();
}
}
Keluaran program
ditunjukkan di sini:
rumah mempunyai:
2 lantai
4 penghuni
2500 luas bangunan
625 luas per orang
kantor mempunyai:
3 lantai
25 penghuni
4200 luas bangunan
168 luas per orang
Akan diperiksa
beberapa elemen kunci pada program ini, dimulai dengan metode LuasPerOrang(). Baris pertama dari LuasPerOrang() adalah
public
void LuasPerOrang() {
Baris ini
mendeklarasikan sebuah metode bernama LuasPerOrang()
yang tidak memiliki parameter. Pendeklarasian ini dispesifikasi sebagai public, sehingga dapat dipakai oleh
bagian lain dari program. Tipe nilai balik metode ini adalah void. Jadi, LuasPerOrang() tidak menghasilkan nilai balik apapun kepada
pemanggil. Baris ini diakhiri dengan kurung kurawal buka untuk mengapit tubuh
metode.
Tubuh metode LuasPerOrang() hanya memuat statemen
ini:
Console.WriteLine(" " + Luas / Penghuni + " luas per orang");
Statemen ini
menampilkan luas per orang dari suatu bangunan dengan membagi Luas oleh Penghuni. Karena setiap objek yang bertipe Bangunan mempunyai salinan sendiri atas Luas dan Penghuni,
ketika LuasPerOrang() dipanggil,
penghitungan melibatkan salinan kedua variabel tersebut dari objek pemanggil.
Metode LuasPerOrang() diakhiri dengan kurung
kurawal tutup. Ini menyebabkan kendali program dialihkan kepada pemanggil.
Berikutnya, akan
ditengok baris kode berikut di dalam Main():
rumah.LuasPerOrang();
Statemen ini
memanggil metode LuasPerOrang() pada
rumah. Yaitu, ia memanggil LuasPerOrang() agar diterapkan pada
objek yang ditunjuk oleh rumah, dengan menggunakan operator dot. Ketika sebuah
metode dipanggil, kendali program dialihkan ke metode tersebut. Ketika metode
berhenti, kendali dialihkan kembali kepada pemanggil.
Pada kasus ini,
pemanggilan terhadap rumah.LuasPerOrang()
akan menampilkan luas per orang dari suatu bangunan yang didefinisikan oleh rumah. Dengan pengertian sama,
pemanggilan terhadap kantor.LuasPerOrang()
akan menampilkan luas per orang dari suatu bangunan yang didefinisikan oleh kantor. Setiap kali LuasPerOrang() dipanggil, ia
menampilkan luar per orang dari objek yang dispesifikasi.
Ada hal yang
sangat penting untuk diperhatikan dalam metode LuasPerOrang(): Variabel instans Luas dan Penghuni
dirujuk secara langsung, tanpa penggunaan operator dot. Ketika metode menggunakan
variabel instans yang didefinisikan oleh kelasnya, metode itu secara langsung
melakukannya, tanpa mereferensi secara eksplisit ke objek dan tanpa menggunakan
operator dot.
Kembali
dari Metode
Secara umum, ada
dua kondisi yang menyebabkan hal ini. Pertama, seperti metode LuasPerOrang() pada contoh sebelumnya,
yaitu ketika kurung kurawal tutup dijumpai. Kedua ketika statemen return dieksekusi. Ada dua format
return: Satu untuk digunakan dalam metode void
(yang tidak menghasilkan nilai balik) dan satu lagi untuk metode yang
menghasilkan nilai balik. Format pertama akan didiskusikan di sini. Bagian
selanjutnya akan menjelaskan bagaimana menghasilkan nilai balik.
Dalam metode void, Anda dapat menyebabkan
penghentian segera dari sebuah metode menggunakan format return seperti ini:
return ;
Ketika statemen
ini dieksekusi, kendali program kembali ke pemanggil, melompati sisa kode di
dalam metode. Sebagai contoh, perhatikan metode ini:
public
void MetodeKu() {
int i;
for(i=0; i<10; i++) {
if(i == 5) return; // berhenti pada 5
Console.WriteLine();
}
}
Di sini, loop for hanya beriterasi dari 0 sampai 5,
karena begitu i sama dengan 5,
metode akan kembali kepada pemanggil. Kepemilikan lebih dari satu statemen return diijinkan dalam sebuah metode,
khususnya ketika terdapat dua atau lebih rute. Sebagai contoh,
public
void MetodeKu() {
// ...
if(selesai) return;
// ...
if(error) return;
}
Mengembalikan
Sebuah Nilai
Metode tanpa
nilai balik jarang dijumpai, dan kebanyakan metode menghasilkan nilai balik.
Pada kenyataannya, kemampuan untuk menghasilkan nilai balik adalah fitur paling
penting yang dimiliki suatu metode. Anda telah melihat sebuah contoh nilai
balik dari fungsi Math.Sqrt() pada
Bab 2 untuk mendapatkan akar kuadrat atas suatu nilai.
Nilai balik
dipakai untuk berbagai kepentingan dalam pemrograman. Pada beberapa kasus,
seperti pada Math.Sqrt(), nilai
balik memuat keluaran dari perhitungan. Pada kasus lain, nilai balik hanya
dipakai untuk mengindikasikan kegagalan atau keberhasilan. Apapun tujuannya,
penggunaan nilai balik dari suatu metode merupakan bagian penting dalam
pemrograman C#.
Metode
menghasilkan nilai balik dengan memanggil rutin menggunakan format return ini:
return nilai;
Di sini, nilai adalah nilai balik.
Anda dapat
menggunakan nilai balik untuk memperbaiki implementasi dari LuasPerOrang(). Daripada hanya
menampilkan luas per orang dari suatu bangunan, pendekatan lebih baik yang bisa
dilakukan adalah meminta LuasPerOrang()
untuk menghasilkan nilai balik. Keuntungan dari pendekatan ini adalah Anda
dapat memakai nilai balik untuk kepentingan lain. Contoh berikut memodifikasi LuasPerOrang() untuk menghasilkan nilai
balik berupa luas per orang dari suatu bangunan.
// Menghasilkan nilai balik dari metode LuasPerOrang().
using System;
class Bangunan {
public int Lantai; // jumlah lantai
public int Luas; // luas bangunan
public int Penghuni; // jumlah penghuni
// Menampilkan luas
per orang.
public int
LuasPerOrang() {
return Luas / Penghuni;
}
}
// menggunakan nilai balik dari LuasPerOrang().
class DemoBangunan {
static void Main() {
Bangunan rumah = new Bangunan();
Bangunan kantor = new Bangunan();
int luasPO; // luas per orang
// menugaskan nilai
ke bidang dalam rumah.
rumah.Penghuni = 4;
rumah.Luas = 2500;
rumah.Lantai = 2;
// menugaskan nilai
ke bidang dalam kantor.
kantor.Penghuni =
25;
kantor.Luas = 4200;
kantor.Lantai = 3;
// mendapatkan luas
per orang untuk rumah
luasPO =
rumah.LuasPerOrang();
Console.WriteLine("rumah mempunyai:\n " +
rumah.Lantai + " lantai\n " +
rumah.Penghuni + " penghuni\n
" +
rumah.Luas + " luas bangunan\n
" +
luasPO + " luas per orang");
Console.WriteLine();
// mendapatkan luas
per orang untuk kantor
luasPO =
kantor.LuasPerOrang();
Console.WriteLine("kantor mempunyai:\n " +
kantor.Lantai + " lantai\n
" +
kantor.Penghuni + " penghuni\n
" +
kantor.Luas + " luas bangunan\n " +
luasPO + " luas per orang");
}
}
Keluaran program
sama dengan yang ditampilkan sebelumnya. Pada program, perhatikan bahwa ketika
metode LuasPerOrang() dipanggil, ia
ditempatkan di sisi kanan operator penugasan. Di sisi kiri operator penugasan
adalah variabel yang akan menerima yang dijadikan nilai balik oleh LuasPerOrang(). Jadi, setelah
luasPO = rumah.LuasPerOrang();
dieksekusi, luas
per orang dari objek rumah disimpan di dalam luasPO. Perhatikan bahwa LuasPerOrang() sekarang mempunyai nilai
balik bertipe int. Ini berarti bahwa
ia akan mengembalikan sebuah nilai integer kepada pemanggil. Tipe nilai balik
suatu metode penting karena tipe data yang dikembalikan oleh metode harus
kompatibel dengan tipe nilai balik yang dispesifikasi oleh metode. Jadi, jika
Anda menginginkan sebuah metode untuk mengembalikan data bertipe double, maka tipe nilai baliknya harus
bertipe double.
Meskipun,
program sebelumnya benar, tetapi tidak ditulis seefisien mungkin. Pada
kenyataannya, tidak diperlukan variabel luasPO.
Pemanggilan terhadap LuasPerOrang()
dapat dipakai di dalam statemen WriteLine()
secara langsung, seperti ditunjukkan di sini:
Console.WriteLine("rumah mempunyai:\n " +
rumah.Lantai + " lantai\n " +
rumah.Penghuni + " penghuni\n " +
rumah.Luas + " luas bangunan\n " +
rumah. LuasPerOrang() +
" luas per orang");
Pada kasus ini, ketika
WriteLine() dieksekusi, rumah.LuasPerOrang() akan dipanggil
secara otomatis, dan nilai baliknya dilewatkan kepada WriteLine(). Di samping itu, Anda dapat memakai pemanggilan
terhadap LuasPerOrang() dimanapun
luas per orang dari sebuah objek Bangunan
diperlukan. Sebagai contoh, statemen ini membandingkan luas per orang atas dua
bangunan:
if(b1.LuasPerOrang()
> b2. LuasPerOrang ())
Console.WriteLine("b1 mempunyai
luas lebih besar untuk setiap orang");
Menggunakan
Parameter
Adalah
memungkinkan untuk melewatkan satu atau lebih nilai kepada sebuah metode ketika
metode itu dipanggil. Nilai yang dilewatkan kepada metode disebut dengan
argumen. Di dalam metode, variabel yang menerima argumen disebut dengan
parameter formal, atau hanya parameter. Parameter dideklarasikan dan diapit
sepasang kurung yang ditempatkan setelah nama metode. Sintaks deklarasi
parameter sama dengan deklarasi variabel. Skop suatu parameter adalah tubuh
metodenya.
Berikut adalah
contoh sederhana yang menggunakan parameter. Di dalam kelas PeriksaAngka, metode apaPrima() menghasilkan true jika nilai yang dilewatkan adalah
prima. Sebaliknya, dihasilkan nilai balik false.
Oleh karena itu, apaPrima()
mempunyai tipe nilai balik bool.
// Contoh sederhana yang
menggunakan parameter.
using System;
class PeriksaAngka {
// Menghasilkan true jika x prima.
public
bool apaPrima(int x) {
if(x
<= 1) return false;
for(int i=2; i <= x/i; i++)
if((x
%i) == 0) return false;
return
true;
}
}
class DemoParameter {
static
void Main() {
PeriksaAngka ob = new PeriksaAngka();
for(int i=2; i < 10; i++)
if(ob.apaPrima(i))
Console.WriteLine(i + " prima.");
else
Console.WriteLine(i + " bukan prima.");
}
}
Berikut adalah keluaran
yang dihasilkan program:
2 prima.
3 prima.
4 bukan prima.
5 prima.
6 bukan prima.
7 prima.
8 bukan prima.
9 bukan prima.
Di dalam
program, apaPrima() dipanggil
delapan kali, dan setiap kali dipanggil, nilai berbeda dilewatkan. Akan
diperiksa proses ini lebih dekat lagi. Pertama, perhatikan bagaimana apaPrima() dipanggil. Argumen
dispesifikasi di antara sepasang kurung. Ketika apaPrima() dipanggil pertama kali, kepadanya dilewatkan nilai 2.
Jadi, ketika apaPrima() mulai
dieksekusi, parameter x menerima
nilai 2. Pada pemanggilan kedua, argumennya adalah 3, dan x kemudian mempunyai nilai 3. Pada pemanggilan ketiga, argumennya
adalah 4, yang merupakan nilai yang diterima x, dan seterusnya.
Metode dapat
mempunyai lebih dari satu parameter. Anda hanya perlu mendeklarasikan setiap
parameter, dipisahkan dengan koma. Sebagai contoh, di sini kelas PeriksaAngka diekspansi dengan
menambahkan sebuah metode yang bernama FaktorTerkecilBersama(),
yang menghasilkan nilai balik berupa faktor kecil bersama dari kedua
argumennya.
// Menambahkan sebuah metode yang mengambil dua argumen.
using System;
class PeriksaAngka {
// Menghasilkan true
jika x prima.
public bool apaPrima(int x) {
if(x <= 1) return false;
for(int i=2; i <= x/i; i++)
if((x %i) == 0) return false;
return true;
}
// Menghasilkan
faktor terkecil bersama.
public int FaktorTerkecilBersama(int a, int b) {
int maks;
if(apaPrima(a) || apaPrima(b)) return 1;
maks = a < b ? a
: b;
for(int i=2; i <= maks/2; i++)
if(((a%i) == 0) && ((b%i) ==
0)) return i;
return 1;
}
}
class DemoParameter
{
static void Main()
{
PeriksaAngka ob
= new PeriksaAngka();
int a, b;
for (int i = 2; i < 10; i++)
if (ob.apaPrima(i)) Console.WriteLine(i
+ " prima.");
else Console.WriteLine(i + " bukan
prima.");
a = 7;
b = 8;
Console.WriteLine("Faktor terkecil bersama untuk " +
a + " dan " + b +
" adalah " +
ob.FaktorTerkecilBersama(a, b));
a = 100;
b = 8;
Console.WriteLine("Faktor terkecil bersama untuk " +
a + " dan " + b +
" adalah " +
ob.FaktorTerkecilBersama(a, b));
a = 100;
b = 75;
Console.WriteLine("Faktor terkecil bersama untuk " +
a + " dan " + b +
" adalah " +
ob.FaktorTerkecilBersama(a, b));
}
}
Perhatikan bahwa
ketika FaktorTerkecilBersama()
dipanggil, argumen-argumen juga dipisahkan dengan koma. Keluaran dari program
ditunjukkan di sini:
2 prima.
3 prima.
4 bukan prima.
5 prima.
6 bukan prima.
7 prima.
8 bukan prima.
9 bukan prima.
Faktor terkecil bersama untuk 7 dan 8 adalah 1
Faktor terkecil bersama untuk 100 dan 8 adalah 2
Faktor terkecil bersama untuk 100 dan 75 adalah 5
Ketika
menggunakan parameter jamak, setiap parameter menspesifikasi tipenya sendiri,
yang bisa berbeda dari lainnya. Sebagai contoh, berikut adalah sah:
int MetodeKu(int a, double b, float c) {
// ...
Menambahkan
Metode Terparameterisasi Ke Bangunan
Anda dapat
menambahkan sebuah metode terparameterisasi ke dalam kelas Bangunan. Metode yang akan ditambahkan mempunyai kemampuan untuk
menghitung jumlah maksimum penghuni untuk sebuah bangunan, bila diasumsikan
bahwa setiap penghuni memerlukan luas minimum. Metode baru ini dinamakan MaksPenghuni(), yang ditampilkan di
sini:
// Menghasilkan nilai balik berupa jumlah maksimum
penghuni jika
// setiap penghuni memerlukan luas minimum yang
dispesifikasi.
public
int MaksPenghuni(int minLuas) {
return Luas / minLuas;
}
Ketika MaksPenghuni() dipanggil, parameter minLuas menerima luas minimum yang
diperlukan setiap penghuni. Metode ini membagi total luas bangunan dengan nilai
tersebut dan memberikan nilai balik. Keseluruhan kelas Bangunan yang mencakup metode MaksPenghuni()
ditampilkan di sini:
/* Menambahkan sebuah metode terparameterisasi yang
menghitung
jumlah maksimum
penghuni yang menghuni sebuah bangunan
bila diasumsikan
setiap penghuni memerlukan
luas minimum yang
dispesifikasi.
*/
using System;
class Bangunan
{
public int Lantai; // jumlah lantai
public int Luas; // luas bangunan
public int Penghuni; // jumlah penghuni
// Menampilkan luas
per orang.
public int LuasPerOrang()
{
return Luas / Penghuni;
}
// Memberikan nilai
balik berupa jumlah maksimum penghuni
// jika setiap
penghuni sedikitnya memerlukan luas minimum
// yang
dispesifikasi.
public int MaksPenghuni(int minLuas)
{
return Luas / minLuas;
}
}
// menggunakan MaksPenghuni().
class DemoBangunan
{
static void Main()
{
Bangunan rumah
= new Bangunan();
Bangunan kantor
= new Bangunan();
int luasPO; // luas per orang
// menugaskan
nilai ke bidang dalam rumah.
rumah.Penghuni
= 4;
rumah.Luas =
2500;
rumah.Lantai =
2;
// menugaskan
nilai ke bidang dalam kantor.
kantor.Penghuni
= 25;
kantor.Luas =
4200;
kantor.Lantai =
3;
Console.WriteLine("Penghuni maksimum rumah jika setiap
penghuni mempunyai " +
30 + " meter persegi:
" +
rumah.MaksPenghuni(30));
Console.WriteLine("Penghuni
maksimum kantor jika setiap penghuni mempunyai " +
30 + " meter persegi:
" +
kantor.MaksPenghuni(30));
}
}
Keluaran program
ditunjukkan di sini:
Penghuni maksimum rumah jika setiap penghuni mempunyai 30
meter persegi: 83
Penghuni maksimum kantor jika setiap penghuni mempunyai 30
meter persegi: 140
Menghindari
Kode Yang Tak Dapat Dieksekusi
Ketika
menciptakan metode, Anda harus menghindari situasi dimana terdapat penggalan
kode, pada sembarang situasi, yang tak bisa dieksekusi. Kompiler akan menampilkan
pesan peringatan jika Anda menciptakan sebuah metode yang memuat kode yang tak
dieksekusi:
public
void MetodeKu() {
char a, b;
// ...
if(a==b) {
Console.WriteLine("sama");
return;
}
else {
Console.WriteLine("tidak sama");
return;
}
Console.WriteLine("ini kode yang tidak bisa dieksekusi");
}
Di sini, metode MetodeKu() akan selalu kembali kepada
pemanggil sebelum statemen terakhir WriteLine()
dieksekusi. Jika Anda mencoba mengkompilasi metode ini, maka pesan peringatan
akan dibangkitkan kompiler.
Konstruktor
Pada beberapa
contoh sebelumnya, variabel instans dari tiap objek Bangunan harus ditetapkan secara manual menggunakan runtun
statemen, seperti
rumah.Penghuni = 4;
rumah.Luas = 2500;
rumah.Lantai = 2;
Pendekatan
semacam ini tidak akan pernah dipakai di dalam kode C# yang ditulis secara
profesional. Pendekatan lain untuk melakukan hal ini adalah menggunakan
konstruktor.
Konstruktor menginisialisasi
objek ketika diciptakan. Konstruktor mempunyai nama sama dengan kelasnya dan
secara sintaks sama dengan metode. Namun, konstruktor tidak memiliki nilai
balik. Bentuk umum atas sebuah konstruktor ditampilkan di sini:
akses nama-kelas(daftar-param) {
// kode
konstruktor
}
Secara umum,
Anda akan menggunakan konstruktor untuk memberikan nilai awal bagi variabel
instans yang didefinisikan oleh kelas atau untuk melakukan prosedur awal yang
dibutuhkan untuk membentuk objek utuh. Di samping itu, biasanya akses dideklarasikan
public karena normalnya dipanggil dari luas kelasnya. daftar-param bisa kosong,
atau bisa menspesifikasi satu atau lebih parameter.
Semua kelas
mempunyai konstruktor, tak peduli apakah Anda definisikan atau tidak, karena C#
secara otomatis menyediakan sebuah konstruktor default yang menyebabkan semua
variabel anggota diinisialisasi dengan nilai defaultnya. Untuk tipe nilai,
nilai default adalah nol. Untuk tipe bool,
nilai defaultnya adalah false. Untuk tipe referensi, nilai defaultnya adalah
null. Namun, begitu Anda mendefinisikan konstruktor sendiri, konstruktor
default tidak lagi digunakan. Berikut adalah contoh sederhana yang menggunakan
sebuah konstruktor.
// Konstruktor sederhana.
using System;
class KelasKu {
public
int x;
public
KelasKu() {
x = 10;
}
}
class DemoKonst {
static
void Main() {
KelasKu t1 = new KelasKu();
KelasKu t2 = new KelasKu();
Console.WriteLine(t1.x
+ " " + t2.x);
}
}
Pada contoh ini,
konstruktor untuk KelasKu adalah
public KelasKu() {
x = 10;
}
Perhatikan bahwa
konstruktor dispesifikasi sebagai public.
Ini karena konstruktor akan dipanggil dari kode yang didefinisikan dari luar
kelasnya. Konstruktor ini menugaskan nilai 10 kepada variabel instans x dari KelasKu. Konstruktor ini dipanggil oleh new ketika sebuah objek diciptakan. Sebagai contoh, pada baris
KelasKu t1 = new KelasKu();
konstruktor KelasKu() dipanggil pada objek t1, memberikan nilai 10 kepada t1.x. Hal ini berlaku juga untuk objek t2. Setelah konstruksi, t2.x memiliki nilai 10. Jadi, keluaran
program adalah
10 10
Konstruktor
Terparameterisasi
Pada contoh
sebelumnya, konstruktor tanpa parameter digunakan. Hal ini berguna pada
beberapa situasi, tetapi pada banyak kesempatan Anda memerlukan konstruktor
yang mempunyai satu atau lebih parameter. Parameter dicantumkan dalam sebuah konstruktor
dengan cara yang sama dengan pencantuman parameter pada sebuah metode, yaitu
Anda hanya perlu mendeklarasikannya di dalam kurung setelah nama konstruktor.
Sebagai contoh, pada KelasKu di sini
diberikan sebuah konstruktor terparameterisasi:
// Konstruktor sederhana.
using System;
class KelasKu {
public
int x;
public
KelasKu(int i)
{
x = i;
}
}
class DemoKonst {
static void Main() {
KelasKu t1 = new KelasKu(10);
KelasKu t2 = new KelasKu(88);
Console.WriteLine(t1.x
+ " " + t2.x);
}
}
Keluaran program
adalah
10 88
Pada versi
program ini, konstruktor KelasKu()
mendefinisikan satu parameter i,
yang dipakai untuk menginisialisasi variabel instans x. Jadi, ketika baris
KelasKu t1 = new KelasKu(10);
dieksekusi,
nilai 10 dilewatkan kepada i, yang
kemudian ditugaskan kepada x.
Menambahkan
Konstruktor Ke Dalam Kelas Bangunan
Anda bisa
memperbaiki kelas Bangunan dengan
menambahkan sebuah konstruktor yang secara otomatis menginisialisasi bidang Lantai, Luas, dan Penghuni
ketika suatu objek dikonstruksi. Perhatikan secara khusus bagaimana objek-objek
Bangunan diciptakan.
// Menambahkan konstruktor
pada kelas Bangunan
using System;
class Bangunan
{
public
int Lantai; // jumlah lantai
public
int Luas; // luas bangunan
public
int Penghuni; // jumlah penghuni
// Konstruktor terparameterisasi untuk
Bangunan.
public
Bangunan(int f, int a, int o) {
Lantai = f;
Luas = a;
Penghuni = o;
}
// Menampilkan luas per orang.
public
int LuasPerOrang() {
return
Luas / Penghuni;
}
// Memberikan nilai balik berupa jumlah
maksimum penghuni
// jika setiap penghuni sedikitnya
memerlukan luas minimum
// yang dispesifikasi.
public
int MaksPenghuni(int minLuas) {
return
Luas / minLuas;
}
}
// menggunakan konstruktor
Bangunan terparameterisasi.
class DemoBangunan
{
static
void Main()
{
Bangunan rumah = new Bangunan(2, 2500, 4);
Bangunan kantor = new Bangunan(3, 4200, 25);
Console.WriteLine("Penghuni
maksimum rumah jika setiap penghuni mempunyai "
+
30 + " meter persegi: " +
rumah.MaksPenghuni(30));
Console.WriteLine("Penghuni
maksimum kantor jika setiap penghuni mempunyai " +
30 + " meter persegi: " +
kantor.MaksPenghuni(30));
}
}
Keluaran program
ini sama dengan versi sebelumnya.
Kedua rumah dan kantor diinisialisasi dengan konstruktor Bangunan() ketika diciptakan. Setiap objek diinisialisasi seperti
yang dispesifikasi di dalam parameter konstruktor. Sebagai contoh, pada baris
berikut
Bangunan rumah = new Bangunan(2, 2500, 4);
nilai 2, 2500,
dan 4 dilewatkan kepada konstruktor Bangunan()
ketika new menciptakan objek. Jadi,
salinan dari Lantai, Luas, dan Penghuni pada objek rumah
akan memuat nilai 2, 2500, dan 4, berturut-turut.
Operator
new
Setelah Anda
mengetahui lebih banyak tentang kelas dan konstruktor, sekarang saatnya untuk
melihat lebih dekat tentang operator new.
Operator new mempunyai bentuk umum:
new nama-kelas(daftar-arg)
Di sini, nama-kelas adalah nama
kelas yang sedang diinstansiasi. Nama kelas yang diikuti oleh sepasang kurung
menspesifikasi konstruktor untuk kelas tersebut. Jika sebuah kelas tidak
mendefinisikan konstruktornya sendiri, maka operator new akan menggunakan konstruktor default yang disediakan C#. Jadi, new dapat dipakai untuk menciptakan
sebuah objek bertipe sembarang.
Bila memori
terbatas, adalah hal mungkin bahwa new
tidak bisa mengalokasikan memori untuk sebuah objek karena memori yang ada
tidak cukup. Jika hal ini terjadi, eksepsi runtime akan terjadi. (Anda akan
belajar tentang eksepsi pada Bab 12). Untuk semua program pada buku ini, Anda
tidak perlu khawatir tentang kehabisan memori, tetapi Anda bisa saja
mengalaminya ketika menulis program untuk menyelesaikan permasalahan di dunia
aplikasi.
Menggunakan
new Dengan Tipe Nilai
Pada titik ini,
Anda mungkin bertanya mengapa Anda tidak perlu menggunakan new untuk variabel bertipe nilai, seperti int atau float? Dalam
C#, variabel bertipe nilai memuat nilainya sendiri. Memori untuk menampung
nilai ini secara otomatis disediakan ketika program dijalankan. Jadi, tidak ada
kebutuhan untuk secara eksplisit mengalokasikan memori ini menggunakan new. Kebalikannya, variabel referensi
menyimpan referensi yang menunjuk ke suatu objek. Memori untuk menampung objek
ini harus dialokasikan secara dinamis selama eksekusi program berlangsung.
Pengumpulan
Sampah dan Destruktor
Seperti yang
Anda lihat, objek secara dinamis dialokasikan menggunakan operator new. Tentu saja, memori terbatas dan
bisa habis. Oleh karena itu, adalah hal yang memungkinkan bila new gagal mengalokasikan memori karena
memori tidak cukup untuk menciptakan objek yang diinginkan. Karena alasan ini,
salah satu komponen kunci dari skema alokasi dinamis adalah pembebasan memori
dari objek-objek yang tidak lagi digunakan. Pada banyak bahasa pemrograman,
pembebasan memori dilakukan secara manual. Sebagai contoh, dalam C++, operator delete dipakai untuk membebaskan
memori. Namun, C# menggunakan pendekatan lain: pengumpulan sampah!.
Sistem
pengumpulan sampah memori dalam C# untuk membebaskan memori dilakukan secara
otomatis, tanpa sepengetahuan programer. Mekanisme tersebut bekerja seperti
ini: Ketika tidak ada referensi yang menunjuk ke sebuah objek, objek tersebut
diasumsikan tidak lagi diperlukan, dan memori yang ditempati objek tersebut akan
dibebaskan dan dikumpulkan.
Destruktor
Adalah hal yang
memungkinkan bagi Anda untuk mendefinisikan sebuah metode yang dipanggil untuk
menghancurkan suatu objek. Metode ini dikenal dengan destruktor dan bisa
dipakai dalam situasi khusus untuk memastikan bahwa sebuah objek dihancurkan
secara sempurna. Sebagai contoh, Anda bisa memakai destruktor untuk memastikan
bahwa sumberdaya sistem yang dimiliki sebuah objek telah dibebaskan. Anda harus
mengingat bahwa destruktor merupakan fitur tingkat tinggi yang hanya bisa
diterapkan pada kasus-kasus tertentu dan jarang.
Destruktor
mempunyai bentuk umum:
~nama-kelas( ) {
// kode
destruktor
}
Di sini, nama-kelas adalah nama
kelas. Oleh karena itu, destruktor dideklarasikan seperti konstruktor kecuali
bahwa ia diawali dengan suatu tilde (~). Perhatikan bahwa tidak ada tipe nilai
balik dan tidak ada argumen.
Untuk
menambahkan destruktor ke dalam sebuah kelas, Anda hanya perlu mencantumkannya
sebagai anggota. Destruktor dipanggil kapanpun objek dari kelas tersebut
dihancurkan. Di dalam destruktor, Anda bisa menspesifikasi aksi yang perlu
dilakukan sebelum sebuah objek dihancurkan.
Program berikut
mendemonstrasikan sebuah destruktor. Program bekerja dengan menciptakan dan
menghancurkan banyak objek. Selama proses ini, pada titik tertentu kolektor
sampah akan diaktivasi, dan destruktor untuk objek akan dipanggil.
// Demonstrasi destruktor.
using System;
class Hancur {
public
int x;
public
Hancur(int i) {
x = i;
}
// dipanggil ketika objek dihancurkan.
~Hancur() {
Console.WriteLine("Menghancurkan " + x);
}
// Membangkitkan sebuah objek yang dengan
segera dihancurkan.
public
void Generator(int i) {
Hancur o = new Hancur(i);
}
}
class DemoDestruktor {
static
void Main() {
int
hitung;
Hancur ob = new Hancur(0);
/* Sekarang, sejumlah banyak objek
dibangkitkan. Pada
titik tertentu, kolektor sampah akan
diaktivasi.
Penting: Anda mungkin perlu menambah
jumlah objek
yang akan dibangkitkan untuk memaksa
kolektor
sampah diaktivasi */
for(hitung=1;
hitung < 100000; hitung++)
ob.Generator(hitung);
Console.WriteLine("Selasai");
}
}
Berikut adalah
bagaimana program bekerja. Konstruktor menetapkan variabel instans x dengan sebuah nilai. Pada contoh ini,
x dipakai sebagai ID objek.
Destruktor menampilkan nilai x ketika sebuah objek dihancurkan. Yang paling
menarik di sini adalah Generator().
Metode ini menciptakan dan kemudian dengan segera menghapus objek Hancur. Kelas DemoDestruktor menciptakan objek Hancur yang dinamakan ob.
Kemudian menggunakan ob, kelas ini
menciptakan 100 ribu objek dengan memanggil metode Generator() pada ob. Hal
ini menyebabkan penciptaan dan penghancuran 100 ribu objek. Pada titik tertentu
di tengah proses ini, kolektor sampah akan diaktivasi, tergantung sistem
operasi dan hal lainnya.
Katakunci
this
Sebelum
mengakhiri bab ini, penting untuk mengenalkan this. Ketika sebuah metode
dipanggil, ia secara otomatis melewatkan suatu referensi kepada objek
pemanggil. Referensi ini dikenal dengan this.
Untuk memahami ini, perhatikan program berikut yang menciptakan kelas bernama
Persegi. Kelas ini mengenkapsulasi lebar dan tinggi suatu persegi panjang dan
menyertakan sebuah metode yang bernama Luas()
(yang menghasilkan nilai balik luas).
using System;
class Persegi {
public
int Lebar;
public
int Tinggi;
public
Persegi(int w, int h) {
Lebar = w;
Tinggi = h;
}
public
int Luas() {
return
Lebar * Tinggi;
}
}
class MenggunakanPersegi {
static
void Main() {
Persegi r1 = new Persegi(4, 5);
Persegi r2 = new Persegi(7, 9);
Console.WriteLine("Luas dari r1: " + r1.Luas());
Console.WriteLine("Luas dari r2: " + r2.Luas());
}
}
Seperti Anda
ketahui, di dalam sebuah metode, anggota lain dari sebuah kelas dapat diakses
secara langsung, tanpa menggunakan objek atau kualifikasi kelas. Jadi, di dalam
Luas(), statemen
return Lebar * Tinggi;
berarti bahwa
salinan dari Lebar dan Tinggi yang berkaitan dengan objek pemanggil dapat
dikalikan dan hasilnya dijadikan nilai balik. Namun, statemen yang sama dapat
pula ditulis seperti ini:
return this.Lebar * this.Tinggi;
Di sini, this merujuk ke objek yang memanggil Luas(). Jadi, this.Lebar merujuk ke salinan dari Lebar pada objek pemanggil, dan this.Tinggi merujuk ke salinan dari Tinggi pada objek pemanggil. Sebagai contoh, jika Luas() dipanggil pada objek x, maka this pada statemen di atas akan menunjuk ke x. Penulisan statemen tanpa menggunakan this adalah cara singkat.
Hal yang
memungkinkan juga untuk menggunakan this
di dalam sebuah konstruktor. Pada kasus ini, this merujuk ke objek yang sedang diciptakan. Sebagai contoh, di
dalam Persegi(), statemen
Lebar = w;
Tinggi = h;
dapat ditulis
seperti ini:
this.Lebar =
w;
this.Tinggi = h;
Tentu saja,
tidak ada keuntungan dalam melakukan hal itu pada kasus ini. Agar dapat lebih
dipahami, di sini kelas Persegi
ditulis menggunakan referensi this:
using System;
class Persegi {
public
int Lebar;
public
int Tinggi;
public
Persegi(int w, int h) {
this.Lebar
= w;
this.Tinggi
= h;
}
public
int Luas() {
return
Lebar * Tinggi;
}
}
class MenggunakanPersegi {
static
void Main() {
Persegi r1 = new Persegi(4, 5);
Persegi r2 = new Persegi(7, 9);
Console.WriteLine("Luas dari r1: " + r1.Luas());
Console.WriteLine("Luas dari r2: " + r2.Luas());
}
}
No comments:
Post a Comment