Is-a yra tipo santykis — modeliuojamas su paveldėjimu ( ). yra santykis — modeliuojamas su ( ). Pasirinkti teisingą — tai yra pagrindinė modeliavimo sprendimas.
Is-a yra tipo santykis — modeliuojamas su paveldėjimu ( ). yra santykis — modeliuojamas su ( ). Pasirinkti teisingą — tai yra pagrindinė modeliavimo sprendimas.
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
}
Klausimasx: "Ar X yra tam tikro tipo Y, ar X turi/naudoja 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) ✅
Žmonės siekia paveldėjimo kodo kartojimui, net kai santykis iš tikrųjų yra has-a. Jei negalėtumėte pakeisti potklasę bazine klasės visur, tai tikriausiai nėra is-a — naudokite kompoziciją.
Šis skirtumas yra praktinis sprendimo taisyklė už "priimti kompoziciją paveldimu": pasirinkite santykį, kuris yra tikras, o ne tą, kuris sutaupa kelias eilutes.
Kai tai darote teisingai, hierarchija lieka seka ir nuosekli, o tai neleido Liskov pažeidimams, kai "poklasis" negali iš tikrųjų pakeitinti savo tėvinės klasės.