Setelah satu section penuh membedah inheritance, pertanyaan desain muncul: apakah semua pemakaian ulang perilaku harus lewat pewarisan? Mobil, misalnya, bukan jenis mesin; mobil memiliki mesin. Relasi memiliki (has-a) tidak cocok dinyatakan sebagai pewarisan, dan memaksanya justru mengikat class pada detail yang salah. Composition menawarkan jalur lain: class memakai ulang perilaku dengan menampung object class lain sebagai field, lalu mendelegasikan tugas kepadanya.
Komposisi: Membangun dari Bagian #
Dalam composition, class luar menyusun perilakunya dari object bagian yang dibuat di dalamnya. Class bagian tidak perlu dirancang untuk diwarisi, sehingga class bagian bebas berubah sepanjang permukaan publiknya tetap sama. Pola ini membuat arah perubahan lebih terkendali: penggantian bagian tidak mengganggu hierarki apa pun.
Contoh: Mobil dengan Mesin #
public class Mesin
{
public int Tenaga;
public Mesin(int tenaga)
{
Tenaga = tenaga;
}
public void Nyalakan()
{
Console.WriteLine($"Mesin {Tenaga} PK menyala.");
}
}
public class Mobil
{
public Mesin Mesin;
public Mobil(int tenaga)
{
Mesin = new Mesin(tenaga);
}
public void Mulai()
{
Mesin.Nyalakan();
Console.WriteLine("Mobil siap dikendarai.");
}
}
Mobil mobil = new Mobil(150);
mobil.Mulai();Output yang Dihasilkan:
Mesin 150 PK menyala.
Mobil siap dikendarai.Mari kita bedah baris demi baris:
class Mesin: Class bagian ini berdiri sendiri dan tidak menyebut classMobilmana pun, sehingga dapat dipakai oleh mobil, motor, maupun kapal.public Mesin Mesin;: ClassMobilmenampung objectMesinsebagai field; relasi memiliki dinyatakan lewat field, bukan tanda titik dua.Mesin = new Mesin(tenaga);: ConstructorMobilmenyusun bagian internalnya sendiri, sehingga object mobil selalu utuh sejak dibuat.Mesin.Nyalakan();: MethodMulai()mendelegasikan tugas menyalakan ke object bagian;Mobiltidak menyalin logika mesin sama sekali.mobil.Mulai(): Pemanggilan dari luar hanya menyentuh method publikMobil, sementara detail mesin tetap tersembunyi di dalam.
Kapan Memilih yang Mana #
Tabel berikut merangkum dua pendekatan tersebut:
| Aspek | Inheritance | Composition |
|---|---|---|
| Relasi yang dinyatakan | is-a: Mobil adalah Kendaraan | has-a: Mobil memiliki Mesin |
| Ikatan antar class | Kuat; base class dan turunan tumbuh bersama | Longgar; bagian hanya dipakai lewat permukaan publiknya |
| Dampak perubahan | Perubahan base class menjalar ke semua turunan | Perubahan bagian tertahan di dalam class pemakai |
| Fleksibilitas | Satu rantai warisan tunggal | Banyak bagian dapat diganti-ganti |
Dua pendekatan ini bukan pilihan tunggal; desain yang sehat kerap memadukan keduanya, misalnya hierarki Kendaraan yang setiap turunannya mengandung object Mesin. Dengan bab ini, section Inheritance dan Polymorphism tuntas: kita telah berlatih membentuk hierarki, mengatur penggantian perilaku, mengikat kontrak interface, hingga menimbang desainnya secara utuh.