Egy híres idióta öröklési viccre bukkantam
Miért szegények a C programozók?
Mert nincs örökségük.
Erre azt mondanám, hogy A Java programozók szegények, annak ellenére, hogy öröklődnek.
Ennek ellenére határozzuk meg a kontextust, és mondjuk ki a nyilvánvalót.
Mi az öröklődés a Java nyelvben?
Az öröklődés az objektumorientált programozás (OOP) egyik elsődleges pillére, amely lehetővé teszi, hogy egy kódrészlet örökölje egy másik kódrészlet tulajdonságait.
Java nyelvenegy osztály kiterjesztése lehetővé teszi a bővítendő osztály jellemzőinek öröklését. Amikor B kiterjeszti A-t, B az összes jellemzőt (változókat és metódusokat) örökli A-tól.
Az állítás másik módja: Az öröklődés lehetővé teszi olyan közös attribútum- és metóduskészlet meghatározását egy osztályban, amelyet más hasonló osztályok is örökölhetnek.
Miért van szükség az öröklődésre a Java nyelven?
A legközhelyesebb és nagyon nyilvánvaló ok, amellyel találkozni fog, a „lehetővé teszi a kód újrafelhasználását”. Ez azonban nem az egyetlen igazán jó ok, amiért öröklésre van szüksége. Úgy értem, vannak más módok is a kód újrafelhasználásának elérésére. Azt is elérheti, hogy az újrafelhasználható legyen, ha ezt a nagyon „újrafelhasználható kódot” írja be egy másik osztályba, importálja azt az osztályt minden olyan osztályba, amelyre szüksége van az újrafelhasználható kódra, és meghívja a metódusait.
Azt mondanám, hogy az erősebb ok az, amit az öröklés miatt kapsz. Vagyis a futásidejű polimorfizmus és a parent-type hivatkozás használata a gyermekosztály objektumának eléréséhez. Ez segít elkerülni a kódredundanciát, és jelentősen csökkenti a kód mennyiségét.
A futásidejű polimorfizmus vagy metódus-felülbírálás, amelyben a gyermekosztály felülírja a szülőosztály metódusát, jelentősen csökkenti a kód mennyiségét, amelyet egy bizonyos típusú objektumok kezelésére írna. Ha a felülírt toString metódust hívná meg egy for ciklusban különböző objektumok tömbjén. A program a tömbből kiugró objektum típusától függetlenül lefutna, mert minden objektum vagy felülírt toString metódussal rendelkezik, vagy a szülőosztályában meghatározott metódust veszi át.
Szülőtípusra való hivatkozáshoz tegyük fel, hogy van Cipő típusú szülőosztálya, és ebből származtatja a különböző gyermekosztályokat, például Futócipők, Sétacipők, Játékcipők, Alvócipők. Most, ha lenne cipőtartója (ArrayList‹Cipők›), az összes különböző cipőt erre az egyetlen cipőtartóra helyezheti. Ha szükséges, átadhatja ezt az ArrayList-et, biztos lehet benne, hogy Shoes típusú objektumokat ad át. A kódolásnál nem kell feltételes utasításokat írni, csak a szülőtípusra tennéd. Csak a Cipőtípus feltételes utasításának megírása gondoskodik a hasonló gyermektípusokról.
Szóval, mik az öröklés előnyei?
A polimorfizmust, a kevesebb kódolást és a kód újrafelhasználhatóságát kapjuk az öröklődésből. Mindhárom együtt hatalmas ütést ad a programozásban.
Milyen problémákat okoz az öröklődés?
Az öröklődés önmagában nem okoz problémákat. Valójában az olyan nyelvek, mint a Smalltalk, erősen függtek az öröklődéstől.
A megvalósítás módja törékeny alaposztályproblémátokozhat. A gyermekosztály nagymértékben függ a szülőosztálytól. Bármilyen változás a szülő osztályban, megszakíthatja a gyermekosztály megvalósítását, még akkor is, ha semmit nem változtat a gyermekosztályon. Ez is a szoros csatolás egyik formája.
A Effective Java – Joshua Blochban a 16. „Összetétel előnyben részesítése az öröklődés helyett” pont ezt a problémát emeli ki.
Az öröklés hatékony módja a kód újrafelhasználásának, de nem mindig a legjobb eszköz a feladathoz. Nem megfelelő használat esetén törékeny szoftverhez vezet. Biztonságos az öröklődés használata egy csomagon belül, ahol az alosztály és a szuperosztály megvalósítása ugyanazon programozók irányítása alatt áll. Biztonságos az öröklődés használata a kifejezetten kiterjesztésre tervezett és dokumentált osztályok kiterjesztésekor is (17. tétel). A hagyományos betonosztályokból a csomaghatárokon átnyúló öröklés azonban veszélyes. – Joshua Bloch
Ez elvezet minket a Sealed Classes-hoz – ez egy új szolgáltatás a Java 17-es és újabb verziójában. Úgy tűnik, hogy a Sealed osztályok teljes előfeltétele megoldja az Effective Java 16. és 17. pontjában említett problémákat.
A lezárt osztályok pontosan ezt teszik –
- Csak a megadott osztályok számára engedélyezze az osztály kiterjesztését.
- A kiterjesztett osztálynak ugyanabban a csomagban kell lennie.
- Közvetetlenül dokumentálja, hogy az osztályt öröklésre tervezték.
Mikor használjuk az öröklődést?
A szokásos napi programozás során ritkán van lehetőség az öröklődés használatára. A kód újrafelhasználásának nagy része hatékonyan kezelhető a kompozíció használatával.
Csak akkor használja az öröklődést, ha száz százalékig biztos abban, hogy az osztályok között IS-A kapcsolat van. A B osztálynak csak az A osztályt kell kiterjesztenie, ha biztos benne, hogy B az A. Ha kétségei vannak, használja az összetételt.
Ha azonban az alkalmazási követelmény arra készteti, a gyakorlatot követve a szülő- és a gyermekosztályt egy csomagban kell tartani, és az osztályt és a metódusokat kifejezetten öröklésre dokumentálnimegakadályozhatja, hogy az öröklődés hosszú ideig törékeny kódot okozzon.
A kompozíció egy olyan típusú delegálás, amelyben deklarál egy másik osztálytípus privát változóját. Ezután hívja meg az osztály kódját ezzel a változóval.