adalah hubungan — dimodelkan dengan (sebuah ). adalah hubungan — dimodelkan dengan (sebuah ). Memilih yang tepat adalah keputusan pemodelan inti.
adalah hubungan — dimodelkan dengan (sebuah ). adalah hubungan — dimodelkan dengan (sebuah ). Memilih yang tepat adalah keputusan pemodelan inti.
CarVehicleCarEngine// IS-A → inheritance
class Vehicle { void move() {} }
class Car extends Vehicle { } // a Car IS A Vehicle
// HAS-A → composition
class Engine { void start() {} }
class Car2 {
private Engine engine = new Engine(); // a Car HAS AN Engine
void start() { engine.start(); } // delegate to the part
}
Tanyakan: "Apakah X adalah jenis Y, atau apakah X memiliki/menggunakan sebuah Y?"
A Dog IS-A Animal → inheritance ✅
A Car HAS-A Engine → composition ✅
A Square IS-A Shape → inheritance ✅
A Manager HAS Employees → composition (a list) ✅
A Stack HAS-A list (not IS-A) → composition (see earlier pitfall) ✅
Orang-orang sering menggunakan inheritance untuk menggunakan kembali kode, bahkan ketika hubungannya sebenarnya adalah has-a. Jika Anda tidak akan pernah mengganti subclass dengan base di mana-mana, itu mungkin bukan is-a — gunakan composition.
Distingsi ini adalah aturan keputusan praktis di balik "favor composition over inheritance": pilih hubungan yang benar, bukan yang menghemat beberapa baris kode.
Mendapatkan ini dengan benar menjaga hierarki tetap dangkal dan jujur, dan mencegah pelanggaran Liskov di mana sebuah "subtype" tidak dapat benar-benar menggantikan induknya.