Is-a är en typ-relation — modellerad med arv (en Car ). är en -relation — modellerad med (en ). Att välja rätt är ett kärnbeslut vid modellering.
Is-a är en typ-relation — modellerad med arv (en Car ). är en -relation — modellerad med (en ). Att välja rätt är ett kärnbeslut vid modellering.
VehicleCarEngine// 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
}
Fråga: "Är X en typ av Y, eller har/använder X en 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) ✅
Människor söker till arv för att återanvända kod, även när relationen verkligen är has-a. Om du aldrig skulle kunna ersätta subklassen med basen överallt, är det förmodligen inte is-a — använd komposition.
Den här skillnaden är den praktiska beslutsregeln bakom "föredra komposition framför arv": välj den relation som är sann, inte den som sparar några rader.
Att välja rätt håller hierarkierna grunda och ärliga, och förhindrar Liskov-överträdelser där en "undertyp" inte kan ersätta sin överordnade.