Kelas dan Objek

Field, metode, operator new, dan semantik referensi objek.

Daftar isi

Topik ini membahas kelas sebagai kerangka pembentuk object dalam C#, mulai dari deklarasi field dan metode, pembuatan object dengan operator new, hingga semantik reference yang menentukan akibat penyalinan variabel bertipe kelas. Kelas mendeklarasikan data dan perilaku yang dimiliki sekumpulan object, sedangkan object adalah wujud kelas tersebut di memori. Setelah topik ini diselesaikan, kelas sederhana dapat ditulis dan perbedaan antara menyalin reference dengan menyalin nilai dapat dijelaskan.

Kelas, field, dan object#

Field adalah variabel yang dideklarasikan di dalam tubuh kelas dan dimiliki oleh setiap object hasil kelas tersebut. Perilaku dinyatakan sebagai metode, yaitu fungsi yang terikat pada kelas. Keduanya bersama property dan anggota lain membentuk anggota (member) kelas. Deklarasi berikut mendefinisikan kelas Kotak dengan dua field bertipe int dan dua metode yang membaca kedua field itu.

Instance adalah wujud kelas di memori, dan dalam percakapan sehari-hari istilah object dipakai untuk menyebutnya. Operator new membuat instance baru dengan cara mengalokasikan memori, mengisi field dengan nilai awalnya, lalu mengembalikan reference, yakni alamat object yang ditunjuk oleh variabel. Anggota object diakses melalui tanda titik, misalnya k1.Panjang untuk membaca field Panjang milik k1.

csharp Program.cs
// Program: kelas Kotak dengan field, metode, dan dua object yang terpisah.
Kotak k1 = new Kotak();
k1.Panjang = 10;
k1.Lebar = 4;

Console.WriteLine(k1.Luas());
Console.WriteLine(k1.Deskripsi());

Kotak k2 = new Kotak();
k2.Panjang = 30;
k2.Lebar = 2;

Console.WriteLine(k2.Luas());
Console.WriteLine(ReferenceEquals(k1, k2));

class Kotak
{
    public int Panjang;
    public int Lebar;

    public int Luas()
    {
        return Panjang * Lebar;
    }

    public string Deskripsi()
    {
        return $"Kotak {Panjang} x {Lebar}";
    }
}
text Keluaran
40
Kotak 10 x 4
60
False

Dua pemanggilan new pada program di atas menghasilkan dua object yang saling terpisah, sehingga perubahan pada satu object tidak pernah memengaruhi object lainnya. Metode Luas() menghitung hasil dari field milik object yang memanggilnya, yaitu 40 untuk k1 dan 60 untuk k2. Metode ReferenceEquals membandingkan dua reference dan mengembalikan False karena k1 dan k2 menunjuk dua object yang berbeda.

Kumpulan nilai field pada satu saat membentuk keadaan (state) object, dan dua object dari kelas yang sama hanya berbeda melalui keadaannya. Kode kelasnya tetap satu, sedangkan datanya tersebar pada setiap object, dan prinsip inilah yang membuat satu kelas dapat melayani banyak object sekaligus. Penamaan kelas dan anggota yang terbuka mengikuti konvensi C#, yaitu huruf kapital di awal setiap kata, sehingga Kotak, Panjang, dan Luas terbaca sebagai satu kesatuan.

Metode kelas#

Metode mendeklarasikan perilaku yang dapat dilakukan object. Strukturnya sama seperti fungsi pada umumnya, yaitu memiliki daftar parameter, tubuh pernyataan, dan tipe nilai balik, tetapi metode selalu dipanggil melalui sebuah object. Ketika dijalankan, metode membaca field milik object pemanggilnya, sehingga object yang berbeda dapat menghasilkan hasil yang berbeda dari metode yang sama.

csharp Contoh: metode dengan parameter dan nilai balik
var kalkulator = new Kalkulator();
Console.WriteLine(kalkulator.Tambah(3, 4));

class Kalkulator
{
    public int Tambah(int a, int b)
    {
        return a + b;
    }
}
text Keluaran
7

Metode Tambah menerima dua parameter dan mengembalikan jumlahnya, sehingga pemanggilan kalkulator.Tambah(3, 4) menghasilkan 7. Perbedaannya dengan fungsi bebas terletak pada pemiliknya, karena metode hanya dapat dipanggil melalui object atau kelas yang mendeklarasikannya. Metode yang tidak mengembalikan nilai apa pun dideklarasikan dengan tipe void, dan tubuhnya cukup berisi pernyataan tanpa pernyataan return.

Semantik reference#

Variabel bertipe kelas tidak menyimpan isi object, melainkan menyimpan reference ke object tersebut. Penugasan dari satu variabel ke variabel lain menyalin reference-nya saja, sehingga kedua variabel menunjuk object yang sama. Akibatnya, perubahan yang dilakukan melalui satu variabel terlihat pula melalui variabel lainnya.

csharp Contoh: dua variabel menunjuk object yang sama
Kotak k2 = k1; // k2 menunjuk object yang sama dengan k1
k2.Panjang = 25;

Console.WriteLine(k1.Panjang);
Console.WriteLine(ReferenceEquals(k1, k2));
text Keluaran
25
True

Potongan kode di atas melanjutkan program Kotak, sehingga k1 sudah berisi object dengan Panjang bernilai 10. Penugasan Kotak k2 = k1; tidak menduplikasi object, tetapi menduplikasi reference-nya, dan pembuktianya muncul saat k2.Panjang = 25; dibaca ulang melalui k1. Perilaku ini berbeda dengan tipe sederhana seperti int, yang menyalin nilainya langsung tanpa melibatkan reference.

Semantik reference juga berlaku pada argumen metode. Object yang dilewatkan sebagai parameter tidak disalin, dan perubahan di dalam metode terlihat oleh pemanggilnya, karena parameter menerima reference yang sama. Hal ini penting diingat ketika metode yang dipanggil mengubah data object, sebab pemanggilannya tidak menampilkan penanda apa pun tentang perubahan itu.

Kesalahan umum#

  • Menggunakan variabel lokal sebelum objectnya dibuat. Variabel lokal bertipe kelas yang baru dideklarasikan tetapi belum diberi nilai ditolak kompilator dengan error CS0165: Use of unassigned local variable. Buat objectnya dengan new terlebih dahulu sebelum field atau metodenya diakses.
  • Menganggap penugasan menyalin object. Penugasan antarvariabel bertipe kelas hanya menyalin reference, sehingga perubahan melalui variabel kedua memengaruhi variabel pertama. Duplikasi object sungguhan memerlukan pembuatan object baru dengan new atau mekanisme penyalinan yang disediakan tipenya.
  • Mengakses anggota melalui reference yang bernilai null. Field bertipe kelas yang tidak diinisialisasi bernilai null, dan akses anggota melaluinya memunculkan NullReferenceException saat program berjalan. Pastikan object dibuat dengan new sebelum anggotanya digunakan.

Ringkasan#

  • Kelas mendeklarasikan field dan metode, sedangkan object adalah instance kelas yang dibuat dengan operator new dan menyimpan salinan field sendiri.
  • Metode dipanggil melalui object dan membaca field milik object pemanggilnya, sehingga metode yang sama dapat menghasilkan hasil berbeda pada object berbeda.
  • Variabel bertipe kelas menyimpan reference, dan penugasannya menyalin reference itu saja sehingga dua variabel dapat menunjuk satu object yang sama.
  • Tipe struct menyalin nilai saat ditugaskan, sedangkan tipe class menyalin reference, dan perbedaan inilah yang membedakan semantik keduanya.

Referensi#