este o relație de — modelată cu (o mașină ). este o relație de — modelată cu (o mașină ). Alegerea celei corecte este o decizie de modelare fundamentală.
este o relație de — modelată cu (o mașină ). este o relație de — modelată cu (o mașină ). Alegerea celei corecte este o decizie de modelare fundamentală.
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
}
Întreabă-te pe tine: "Este X o fel de Y, sau X are un 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) ✅
Oamenii apelează la inheritance pentru a reutiliza cod, chiar și atunci când relația este de fapt has-a. Dacă nu ai înlocui niciodată subclasa cu baza peste tot, probabil nu este is-a — folosește composition.
Această distincție este regula practică de decizie din spatele "prefera composition peste inheritance": alege relația care este adevărată, nu aceea care economisește câteva linii.
A o face bine ține ierarhiile puțin adânci și cinstite, și previne încălcări Liskov unde un "subtip" nu poate sta de fapt în locul părintelui său.