Is-a on tyyppiä type oleva suhde — mallinnettu periytymisellä (Car is a Vehicle). on sisältävyyttä ilmaiseva suhde — mallinnettu ( ). Oikean valitseminen on ydinmallinnus päätös.
Is-a on tyyppiä type oleva suhde — mallinnettu periytymisellä (Car is a Vehicle). on sisältävyyttä ilmaiseva suhde — mallinnettu ( ). Oikean valitseminen on ydinmallinnus päätös.
CarEngine// 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
}
Kysymys: "Onko X eräänlainen Y, vai onko X:llä 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) ✅
Ihmiset turvautuvat periytymiseen koodin uudelleenkäyttöä varten, vaikka suhde olisikin todella has-a. Jos et voisi koskaan korvata aliluokkaa perusluokalla kaikkialla, se ei luultavasti ole is-a — käytä koostumusta.
Tämä ero on käytännön päätöntösääntö "prefer composition over inheritance" -periaatteen takana: valitse suhde, joka on totta, ei se, joka säästää muutaman rivin.
Sen tekeminen oikein pitää hierarkiat mataliksi ja rehellisiksi, ja se estää Liskov-rikkomuksia, joissa "alityyppi" ei voi todellisuudessa seisoa vanhempansa paikalla.