1. Pegasus

Tingnan natin ang pangatlong prinsipyo ng OOP : inheritance . Ito ay isang napaka-interesante na paksa na madalas mong gamitin. Para sa mga hindi pa nakakaalam, ang programming ay hindi naiiba sa magic. Kaya't magsimula tayo sa isang kawili-wiling pagkakatulad...;

Sabihin nating isa kang wizard na gustong lumikha ng lumilipad na kabayo. Sa isang banda, maaari mong subukang gumawa ng isang pegasus. Ngunit dahil ang pegasi ay hindi umiiral sa kalikasan, ito ay magiging napakahirap. Marami kang kailangang gawin sa iyong sarili. Mas madaling kumuha ng kabayo at i-conjure ang mga pakpak nito.

Sa programming, ang prosesong ito ay tinatawag na "mana". Ipagpalagay na kailangan mong magsulat ng isang napaka-komplikadong klase. Ito ay tumatagal ng mahabang panahon upang magsulat ng code mula sa simula at pagkatapos ay subukan ang lahat sa loob ng mahabang panahon upang maghanap ng mga error. Bakit pumunta sa mahirap na paraan? Mas mainam na tingnan kung mayroon nang ganitong klase.

Ipagpalagay na nakakita ka ng isang klase na ang mga pamamaraan ay nagpapatupad ng 80% ng pag-andar na kailangan mo. Ano ang susunod mong gagawin dito? Maaari mo lamang kopyahin ang code nito sa iyong klase. Ngunit ang solusyon na ito ay may ilang mga kawalan:

  1. Ang klase na makikita mo ay maaaring na-compile sa bytecode, at maaaring wala kang access sa source code nito.
  2. Available ang source code ng klase, ngunit nagtatrabaho ka sa isang kumpanyang maaaring kasuhan ng ilang bilyon para sa paggamit ng kahit 6 na linya ng code ng ibang tao. At saka ka kakasuhan ng employer mo.
  3. Hindi kinakailangang pagdoble ng malaking halaga ng code. Bukod pa rito, kung ang may-akda ng isang panlabas na klase ay nakahanap ng isang bug dito at inaayos ito, magkakaroon ka pa rin ng bug.

Mayroong mas eleganteng solusyon, at hindi ito nangangailangan ng pagkuha ng legal na access sa code ng orihinal na klase. Sa Java, maaari mo lamang ideklara ang klase na iyon bilang magulang ng iyong klase. Katumbas iyon ng pagdaragdag ng code para sa klase na iyon sa sarili mong code. Makikita ng iyong klase ang lahat ng data at lahat ng pamamaraan ng parent class. Halimbawa, magagawa mo ito: minana namin ang "kabayo" at pagkatapos ay idagdag ang "mga pakpak" upang makakuha ng "pegasus"


2. Karaniwang baseng klase

Ang mana ay maaaring gamitin para sa iba pang mga layunin. Sabihin nating mayroon kang sampung klase na halos magkatulad. Mayroon silang parehong data at pamamaraan. Maaari kang lumikha ng isang espesyal na base class, ilipat ang data (at mga nauugnay na pamamaraan) sa base class na ito, at ideklara ang sampung klase na iyon bilang mga inapo. Sa madaling salita, sa bawat klase ay nagpapahiwatig na ang parent class nito ay ang base class na ito.

Kung paanong ang mga bentahe ng abstraction ay ibinunyag lamang sa gilid ng encapsulation, gayundin ang mga pakinabang ng inheritance ay higit na pinahusay kapag gumagamit ng polymorphism. Ngunit malalaman mo ang tungkol dito sa ibang pagkakataon. Ngayon ay titingnan natin ang ilang mga halimbawa ng paggamit ng mana.

Mga piraso ng chess

Ipagpalagay na nagsusulat kami ng isang programa na naglalaro ng chess sa isang tao na gumagamit. Alinsunod dito, kailangan namin ng mga klase upang kumatawan sa mga piraso. Anong mga klase sila?

Kung naglaro ka na ng chess, ang malinaw na sagot ay King, Queen, Bishop, Knight, Rook at Pawn.

Ngunit ang mga klase mismo ay kailangan pa ring mag-imbak ng impormasyon tungkol sa bawat piraso. Halimbawa, ang x at y na mga coordinate, at ang halaga ng piraso. Pagkatapos ng lahat, ang ilang mga piraso ay mas mahalaga kaysa sa iba.

Bilang karagdagan, ang mga piraso ay gumagalaw nang iba, na nangangahulugan na ang mga klase ay magpapatupad ng iba't ibang pag-uugali. Narito kung paano mo matutukoy ang mga ito bilang mga klase:

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
   }
}

Ito ay isang napaka-primitive na paglalarawan ng mga piraso ng chess.

Karaniwang baseng klase

At narito kung paano mo magagamit ang inheritance para bawasan ang dami ng code. Maaari naming dalhin ang mga karaniwang pamamaraan at data sa isang karaniwang klase. Tatawagan natin ito ChessItem. Walang punto sa paglikha ng mga bagay ng ChessItem class, dahil ang klase ay hindi tumutugma sa anumang piraso ng chess . Iyon ay sinabi, ang klase ay magiging kapaki-pakinabang:

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
   }
}

Ito ay isang mahusay na paraan upang pasimplehin ang code para sa mga katulad na bagay. Ang mga benepisyo ay partikular na kapansin-pansin kapag mayroong libu-libong iba't ibang mga bagay at daan-daang mga klase sa proyekto. Kaya't ang tamang napiling parent (base) na mga klase ay nagbibigay-daan sa iyo hindi lamang lubos na pasimplehin ang lohika, ngunit bawasan din ang code ng sampung beses.


3. Class inheritance —extends

Kaya ano ang kinakailangan upang magmana ng isang klase? Para magmana ang isang klase ng isa pa, kailangan mong isulat ang extendskeyword pagkatapos ng deklarasyon ng klase ng bata at pagkatapos ay isulat ang pangalan ng parent na klase. Karaniwan itong mukhang ganito:

class Descendant extends Parent

Ito ang kailangan mong isulat kapag nagdedeklara ng Descendant class. Sa pamamagitan ng paraan, ang isang klase ay maaaring magmana ng isang klase lamang.

Sa larawan, makikita natin na ang isang baka ay nagmana ng isang baboy, na nagmana ng isang manok, na nagmana ng isang itlog. Isang magulang lang! Ang ganitong pamana ay hindi palaging lohikal. Ngunit kapag ang lahat ng mayroon ka ay isang baboy at talagang kailangan mo ng isang baka, madalas na hindi mapigilan ng mga programmer ang pagnanasa na gumawa ng isang baka mula sa isang baboy.

Ang Java ay walang multiple inheritance: ang isang klase ay hindi maaaring magmana ng dalawang klase. Ang bawat klase ay maaari lamang magkaroon ng isang parent class. Kung walang tinukoy na klase ng magulang, ang klase ng magulang ay Object.

Iyon ay sinabi, ang Java ay mayroong maraming pamana ng mga interface. Ito ay bahagyang nagpapagaan sa problema. Pag-uusapan natin ang tungkol sa mga interface sa ibang pagkakataon, ngunit sa ngayon ay patuloy nating tuklasin ang mana.