Is-a je razmerje tipa — modelirano z dedovanjem (avtomobil ). je razmerje — modelirano s (avtomobil ). Izbira pravilnega je ključna odločitev pri modeliranju.
Is-a je razmerje tipa — modelirano z dedovanjem (avtomobil ). je razmerje — modelirano s (avtomobil ). Izbira pravilnega je ključna odločitev pri modeliranju.
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
}
Vprašajte se: "Je X vrsta Y, ali X ima/uporablja 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) ✅
Ljudje se zatekajo k dedovanju za ponovno uporabo kode, tudi ko je razmerje pravzaprav has-a. Če ne bi nikoli zamenjali podrazreda z osnovno klaso povsod, verjetno ne gre za is-a — uporabite kompozicijo.
Ta razlika je praktično pravilo odločanja za "podpiramo kompozicijo pred dedovanjem": izberite razmerje, ki je resnično, ne tistega, ki prihrani nekaj vrstic kode.
Pravilna izbira drži hierarhije plitve in iskrene ter preprečuje kršitve Liskovega principa, kjer "podtip" ne more dejansko nadomestiti svoje nadklase.