Method warisan dari bab sebelumnya berperilaku sama untuk semua turunan. Padahal dalam dunia hewan, setiap jenis burung bersuara berbeda, dan memaksa semua turunan menjalankan pesan generik membuat program kurang bermakna. Kata kunci virtual menandai method base class yang boleh diganti, sedangkan override menyatakan penggantian pada derived class. Section Pemrograman Berorientasi Objek telah memperkenalkan pasangan ini; bab ini membedah mekanismenya lebih jauh, termasuk rantai override antar generasi turunan.

Pasangan virtual dan override #

Method yang boleh diganti wajib ditandai virtual di base class. Derived class kemudian menulis versi penggantinya dengan override, dan kedua versi wajib memiliki nama, parameter, serta return type yang sama. Compiler memeriksa kecocokan pasangan tersebut pada waktu kompilasi, sedangkan pemilihan versi yang benar-benar dijalankan terjadi pada saat program berjalan.

Contoh: Rantai Override Tiga Level #

csharp
public class Hewan
{
    public virtual void Bersuara()
    {
        Console.WriteLine("Hewan mengeluarkan suara.");
    }
}

public class Burung : Hewan
{
    public override void Bersuara()
    {
        Console.WriteLine("Burung: Cip cip!");
    }
}

public class Perkutut : Burung
{
    public override void Bersuara()
    {
        Console.WriteLine("Perkutut: Kur kur!");
    }
}

Hewan hewan = new Hewan();
hewan.Bersuara();

Burung burung = new Burung();
burung.Bersuara();

Perkutut perkutut = new Perkutut();
perkutut.Bersuara();

Output yang Dihasilkan:

text
Hewan mengeluarkan suara.
Burung: Cip cip!
Perkutut: Kur kur!

Mari kita bedah baris demi baris:

  1. public virtual void Bersuara(): Kata kunci virtual memberi izin kepada setiap turunan Hewan untuk mengganti isi method ini.
  2. public override void Bersuara() pada Burung: Versi Burung menggantikan versi Hewan, sehingga output baris kedua berasal dari Burung.
  3. public override void Bersuara() pada Perkutut: Perkutut mewarisi Burung, dan method hasil override tetap virtual, sehingga rantai penggantian dapat berlanjut ke generasi berikutnya.
  4. Tiga pemanggilan Bersuara(): Setiap object menjalankan versi terdekat dalam rantai turunannya; perkutut memakai versi Perkutut, bukan versi Burung atau Hewan.

Memperluas Implementasi dengan base #

Turunan kadang perlu menjalankan versi base class terlebih dahulu, lalu menambahkan perilaku sendiri:

csharp
public class Beo : Burung
{
    public override void Bersuara()
    {
        base.Bersuara();
        Console.WriteLine("Beo menirukan suara manusia.");
    }
}

Beo beo = new Beo();
beo.Bersuara();

Output yang Dihasilkan:

text
Burung: Cip cip!
Beo menirukan suara manusia.

Baris base.Bersuara(); menjalankan versi Burung sebelum baris tambahan dicetak, sehingga output memuat dua baris. Pola ini cocok untuk perilaku berlapis seperti pencatatan sebelum aksi utama.

Empat aturan menjaga override tetap konsisten: signature wajib sama persis, visibility versi override tidak boleh lebih ketat daripada versi base, hanya member virtual/abstract/override yang boleh di-override, dan method hasil override tetap virtual untuk turunan berikutnya. Bab tentang sealed members menunjukkan cara menghentikan rantai tersebut.