1. Pegazus

Nézzük meg mélyebben az OOP harmadik alapelvét : az öröklődést . Ez egy nagyon érdekes téma, amelyet gyakran fogsz használni. Az avatatlanok számára a programozás megkülönböztethetetlen a varázslattól. Kezdjük tehát egy érdekes hasonlattal...;

Tegyük fel, hogy Ön egy varázsló, aki repülő lovat akar alkotni. Egyrészt meg lehetne próbálni egy pegazust varázsolni. De mivel a pegazik nem léteznek a természetben, ez nagyon nehéz lesz. Sokat kell majd tennie magának. Sokkal könnyebb fogni egy lovat és megvarázsolni a szárnyait.

A programozásban ezt a folyamatot "öröklődésnek" nevezik. Tegyük fel, hogy egy nagyon összetett osztályt kell írnod. Sok időbe telik, amíg a nulláról megírod a kódot, majd hosszasan tesztelsz mindent, hogy hibákat keress. Miért a nehezebb utat? Jobb megnézni, hogy létezik-e már ilyen osztály.

Tegyük fel, hogy talál egy osztályt, amelynek metódusai megvalósítják a szükséges funkciók 80%-át. Mit csinálsz vele legközelebb? Egyszerűen bemásolhatod a kódját az osztályodba. Ennek a megoldásnak azonban számos hátránya van:

  1. Lehet, hogy a megtalált osztály már bájtkódba van fordítva, és előfordulhat, hogy nem fér hozzá a forráskódjához.
  2. Az osztály forráskódja megvan, de te egy olyan cégnél dolgozol, amit akár 6 soros kód felhasználásáért is beperelhetnek pár milliárdra. És akkor a munkáltatója bepereli.
  3. Nagy mennyiségű kód szükségtelen megkettőzése. Továbbá, ha egy külső osztály szerzője hibát talál benne és kijavítja, akkor is megmarad a hiba.

Létezik egy elegánsabb megoldás is, amelyhez nem szükséges legális hozzáférést szerezni az eredeti osztály kódjához. Java nyelven egyszerűen deklarálhatja az osztályt az osztály szülőjeként. Ez egyenértékű azzal, mintha az adott osztály kódját hozzáadná a saját kódjához. Az osztálya látni fogja a szülőosztály összes adatát és metódusát. Például megteheti ezt: örököljük a „ló” kifejezést, majd hozzáadjuk a „szárnyakat”, hogy „pegazust” kapjunk.


2. Közös alaposztály

Az öröklés más célokra is felhasználható. Tegyük fel, hogy tíz nagyon hasonló osztálya van. Ugyanazok az adatok és módszerek. Létrehozhat egy speciális alaposztályt, áthelyezheti az adatokat (és a kapcsolódó metódusokat) ebbe az alaposztályba, és ezt a tíz osztályt leszármazottnak nyilváníthatja. Más szavakkal, minden osztályban jelezze, hogy a szülőosztálya ez az alaposztály.

Ahogyan az absztrakció előnyei csak az oldalsó tokozás mellett mutatkoznak meg, úgy az öröklődés előnyei is jelentősen megnőnek a polimorfizmus alkalmazásakor. De erről egy kicsit később fogsz tudni. Ma számos példát fogunk megvizsgálni az öröklődés használatára.

Sakkfigurák

Tegyük fel, hogy írunk egy programot, amely egy emberi felhasználóval sakkozik. Ennek megfelelően osztályokra van szükségünk a darabok ábrázolásához. Milyen osztályok lennének?

Ha valaha sakkozott, a kézenfekvő válasz: király, királynő, püspök, lovag, bástya és gyalog.

De maguknak az osztályoknak továbbra is információkat kell tárolniuk minden egyes darabról. Például az x és y koordináták, valamint a darab értéke. Hiszen egyes darabok értékesebbek, mint mások.

Ezenkívül a darabok eltérően mozognak, ami azt jelenti, hogy az osztályok eltérő viselkedést fognak megvalósítani. A következőképpen határozhatja meg őket osztályként:

class King
{
   int x;
   int y;
   int worth;

   void kingMove()
   {
     // Code that decides
     // how to move
     // the king
   }
}
class Queen
{
   int x;
   int y;
   int worth;

   void queenMove()
   {
     // Code that decides
     // how to move
     // the queen
   }
}
class Rook
{
   int x;
   int y;
   int worth;

   void rookMove()
   {
     // Code that decides
     // how to move
     // the rook
   }
}
class Knight
{
   int x;
   int y;
   int worth;

   void knightMove()
   {
     // Code that decides
     // how to move
     // the knight
   }
}
class Bishop
{
   int x;
   int y;
   int worth;

   void bishopMove()
   {
     // Code that decides
     // how to move
     // the bishop
   }
}
class Pawn
{
   int x;
   int y;
   int worth;

   void pawnMove()
   {
     // Code that decides
     // how to move
     // the pawn
   }
}

Ez a sakkfigurák nagyon primitív leírása.

Közös alaposztály

És itt van, hogyan használhatja az öröklődést a kód mennyiségének csökkentésére. A közös metódusokat és adatokat egy közös osztályba hozhatjuk. Majd hívjuk ChessItem. Nincs értelme az objektumokat létrehozni ChessItem class, mivel az osztály nem felel meg egyetlen sakkfigurának sem . Ennek ellenére az osztály nagyon hasznosnak bizonyul majd:

class King extends ChessItem
{
   void kingMove()
   {
     // Code that decides
     // how to move the king
   }
}
class Queen extends ChessItem
{
   void queenMove()
   {
     // Code that decides
     // how to move the queen
   }
}
class Rook extends ChessItem
{
   void rookMove()
   {
     // Code that decides
     // how to move the rook
   }
}
class ChessItem
{
   int x;
   int y;
   int worth;
}
class Knight extends ChessItem
{
   void knightMove()
   {
     // Code that decides
     // how to move the knight
   }
}
class Bishop extends ChessItem
{
   void bishopMove()
   {
     // Code that decides
     // how to move the bishop
   }
}
class Pawn extends ChessItem
{
   void pawnMove()
   {
     // Code that decides
     // how to move the pawn
   }
}

Ez egy nagyszerű módja a hasonló objektumok kódjának egyszerűsítésére. Az előnyök különösen észrevehetők, ha több ezer különböző objektum és több száz osztály van a projektben. Tehát a megfelelően kiválasztott szülő (alap) osztályok nemcsak a logikát nagyban leegyszerűsítik, hanem a kódot is tízszeresére csökkentik.


3. Osztály öröklődés —extends

Tehát mi kell egy osztály örökléséhez? Ahhoz, hogy az egyik osztály örököljön egy másikat, be kell írnia a extendskulcsszót a gyermekosztály deklarációja után, majd a szülőosztály nevét. Általában valahogy így néz ki:

class Descendant extends Parent

Ezt kell írni a Descendant osztály deklarálásakor. Egyébként egy osztály csak egy osztályt örökölhet.

A képen azt látjuk, hogy egy tehén örökölt egy disznót, amely egy csirkét, és egy tojást. Csak egy szülő! Az ilyen öröklődés nem mindig logikus. De amikor csak egy disznó van, és valóban szüksége van egy tehénre, a programozók gyakran nem tudnak ellenállni a késztetésnek, hogy sertésből tehenet csináljanak.

A Java-nak nincs többszörös öröklődése: egy osztály nem örökölhet két osztályt. Minden osztálynak csak egy szülőosztálya lehet. Ha nincs megadva szülőosztály, akkor a szülőosztály a Object.

Ennek ellenére a Java több interfész öröklődéssel rendelkezik. Ez némileg enyhíti a problémát. Az interfészekről kicsit később fogunk beszélni, de most folytassuk az öröklődés feltárását.