Kebun binatang digital menyimpan bermacam-macam hewan dalam satu daftar. Kita bisa memanggil Bersuara() satu per satu lewat variable bertipe spesifik, tetapi cara itu tidak efisien saat daftar terus bertambah. Polymorphism menjawab kebutuhan tersebut: satu pemanggilan method yang sama menghasilkan perilaku berbeda sesuai tipe object aslinya. Kata polymorphism sendiri berarti “banyak bentuk”.

Mekanisme Dynamic Dispatch #

Kunci polymorphism adalah pemisahan dua hal: tipe reference dan tipe object. Variable bertipe Hewan boleh menunjuk object Kucing, Sapi, atau Hewan. Saat method virtual dipanggil lewat reference tersebut, runtime memeriksa tipe object aslinya, bukan tipe reference, lalu menjalankan versi override milik object itu. Pemilihan versi saat runtime ini disebut dynamic dispatch, dan hanya berlaku pada method virtual, override, atau abstract. Karena pemilihan terjadi saat program berjalan, kode pemanggil tidak perlu menulis percabangan untuk menentukan tipe object.

Contoh: Satu Loop, Banyak Perilaku #

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

public class Kucing : Hewan
{
    public override void Bersuara()
    {
        Console.WriteLine("Kucing: Meong!");
    }
}

public class Sapi : Hewan
{
    public override void Bersuara()
    {
        Console.WriteLine("Sapi: Moo!");
    }
}

List<Hewan> kebunBinatang = new List<Hewan>
{
    new Kucing(),
    new Sapi(),
    new Hewan()
};

foreach (Hewan hewan in kebunBinatang)
{
    hewan.Bersuara();
}

Output yang Dihasilkan:

text
Kucing: Meong!
Sapi: Moo!
Hewan mengeluarkan suara.

Mari kita bedah baris demi baris:

  1. List<Hewan> kebunBinatang: Daftar ini bertipe Hewan, tetapi isinya boleh object dari class Hewan maupun semua turunannya.
  2. new Kucing() dan new Sapi(): Object spesifik masuk ke daftar bertipe dasar tanpa cast apa pun, karena setiap Kucing adalah Hewan.
  3. foreach (Hewan hewan in kebunBinatang): Setiap elemen dibaca lewat reference bertipe Hewan; loop tidak tahu dan tidak perlu tahu tipe aslinya.
  4. hewan.Bersuara(): Dynamic dispatch memeriksa tipe object asli pada tiap iterasi, sehingga baris yang sama mencetak Kucing: Meong!, Sapi: Moo!, lalu versi dasar.

Reference Dasar, Object Turunan #

Polymorphism juga bekerja pada satu variable, tanpa daftar apa pun:

csharp
Hewan peliharaan = new Kucing();
peliharaan.Bersuara();

Output yang Dihasilkan:

text
Kucing: Meong!

Variable peliharaan bertipe Hewan, tetapi object yang dirujuknya bertipe Kucing. Saat Bersuara() dipanggil, runtime melihat tipe object aslinya, sehingga yang berbunyi adalah versi Kucing. Mekanisme ini sama dengan yang bekerja di dalam loop pada contoh utama.

Dengan polymorphism, kode pemanggil ditulis sekali terhadap tipe dasar, sementara perilaku detail diserahkan kepada masing-masing object.