1 Pegaz

Przyjrzyjmy się bliżej trzeciej zasadzie OOPdziedziczeniu . To bardzo interesujący motyw, z którego będziesz często korzystać. Programowanie dla ignorantów jest nie do odróżnienia od magii. Zacznijmy zatem od takiej ciekawej analogii...;

Powiedzmy, że jesteś czarodziejem i chcesz stworzyć latającego konia. Z jednej strony można było spróbować wyczarować pegaza. Lecz odkąd Pegaz nie istnieje w naturze, będzie to bardzo trudne. Sam musisz dużo zrobić. O wiele łatwiej jest wziąć konia i wyczarować dla niego skrzydła.

Dziedzictwo.  OOP

W programowaniu proces ten nazywany jest „dziedziczeniem”. Załóżmy, że musisz napisać bardzo złożoną klasę. Długo się pisze od podstaw, potem długo wszystko testuje i szuka błędów. Po co iść trudną drogą? Lepiej popatrzeć, ale czy jest już taka klasa?

Załóżmy, że znalazłeś klasę, która za pomocą swoich metod implementuje 80% potrzebnej funkcjonalności. Co dalej z nim zrobić? Możesz po prostu skopiować jego kod do swojej klasy. Ale to rozwiązanie ma kilka wad:

  1. Znalezioną klasę można już skompilować do kodu bajtowego, ale nie masz dostępu do jej kodu źródłowego.
  2. Kod źródłowy klasy jest, ale pracujesz dla firmy, którą można pozwać na kilka miliardów za użycie nawet 6 linijek cudzego kodu. A potem cię zaskarży.
  3. Niepotrzebne powielanie dużej ilości kodu. Ponadto, jeśli autor innej klasy znajdzie w niej błąd i go naprawi, nadal będziesz mieć ten błąd.

Istnieje bardziej subtelne rozwiązanie, bez konieczności uzyskiwania legalnego dostępu do oryginalnego kodu klasy. W Javie możesz po prostu zadeklarować, że ta klasa jest rodzicem twojej klasy. Będzie to równoznaczne z dodaniem kodu tej klasy do własnego kodu. Wszystkie dane i wszystkie metody klasy nadrzędnej pojawią się w Twojej klasie. Na przykład możesz to zrobić: odziedziczyć po „koniu”, dodać „skrzydła” - otrzymamy „pegaza”

Dziedzictwo.  OOP


2. Wspólna klasa bazowa

Dziedziczenie może być również wykorzystywane do innych celów. Powiedzmy, że masz dziesięć klas, które są bardzo podobne, mają te same dane i metody. Możesz utworzyć specjalną klasę bazową, przenieść te dane (oraz metody, które z nimi współpracują) do tej klasy bazowej i zadeklarować, że te dziesięć klas ma po niej dziedziczyć. Te. wskazać w każdej klasie, że ma klasę nadrzędną - daną klasę bazową.

Tak jak korzyści płynące z abstrakcji ujawniają się dopiero po enkapsulacji, korzyści z dziedziczenia są znacznie większe, gdy stosuje się polimorfizm. Ale o tym dowiecie się trochę później. Dzisiaj przyjrzymy się kilku przykładom wykorzystania dziedziczenia.

Szachy

Załóżmy, że piszemy program, który gra w szachy z użytkownikiem, co oznacza, że ​​potrzebujemy klas dla figur. Jakie to miałyby być zajęcia?

Oczywistą odpowiedzią, jeśli kiedykolwiek grałeś w szachy, jest król, dama, goniec, skoczek, wieża i pion.

Ale w samych klasach nadal konieczne byłoby przechowywanie informacji dla każdej figury. Na przykład współrzędne x i y, a także wartość figury. W końcu niektóre liczby są cenniejsze niż inne.

Ponadto pionki poruszają się inaczej, co oznacza, że ​​​​zachowanie klas będzie inne. Oto jak można je opisać jako klasy:

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

   void kingMove()
   {
     // kod, решающий,
     // Jak пойдет
     // король
   }
}
class Queen
{
   int x;
   int y;
   int worth;

   void queenMove()
   {
     // kod, решающий,
     // Jak пойдет
     // ферзь
   }
}
class Rook
{
   int x;
   int y;
   int worth;

   void rookMove()
   {
     // kod, решающий,
     // Jak пойдет
     // ладья
   }
}
class Knight
{
   int x;
   int y;
   int worth;

   void knightMove()
   {
     // kod, решающий,
     // Jak пойдет
     // конь
   }
}
class Bishop
{
   int x;
   int y;
   int worth;

   void bishopMove()
   {
     // kod, решающий,
     // Jak пойдет
     // слон
   }
}
class Pawn
{
   int x;
   int y;
   int worth;

   void pawnMove()
   {
     // kod, решающий,
     // Jak пойдет
     // пешка
   }
}

To bardzo prymitywny opis figur szachowych.

Wspólna klasa bazowa

A oto jak możesz skrócić kod za pomocą dziedziczenia. Moglibyśmy przenieść te same metody i dane do wspólnej klasy. Nazwijmy go ChessItem. Nie ma sensu tworzyć obiektów klasowych ChessItem, ponieważ nie odpowiada im żadna figura szachowa , ale byłoby to bardzo przydatne:

class King extends ChessItem
{
   void kingMove()
   {
     // kod, решающий,
     // Jak пойдет король
   }
}
class Queen extends ChessItem
{
   void queenMove()
   {
     // kod, решающий,
     // Jak пойдет ферзь
   }
}
class Rook extends ChessItem
{
   void rookMove()
   {
     // kod, решающий,
     // Jak пойдет ладья
   }
}
class ChessItem
{
   int x;
   int y;
   int worth;
}
class Knight extends ChessItem
{
   void knightMove()
   {
     // kod, решающий,
     // Jak пойдет конь
   }
}
class Bishop extends ChessItem
{
   void bishopMove()
   {
     // kod, решающий,
     // Jak пойдет слон
   }
}
class Pawn extends ChessItem
{
   void pawnMove()
   {
     // kod, решающий,
     // Jak пойдет пешка
   }
}

To świetny sposób na uproszczenie kodu dla podobnych obiektów. Szczególnie wiele korzyści uzyskujemy, gdy w projekcie są tysiące różnych obiektów i setki klas. Wtedy odpowiednio dobrane klasy nadrzędne (bazowe) potrafią nie tylko znacznie uprościć logikę, ale i zredukować kod dziesiątki razy.


3. Dziedziczenie klasowe -extends

Co więc trzeba zrobić, aby odziedziczyć klasę? Aby dziedziczyć jedną klasę z drugiej, musisz podać słowo kluczowe po zadeklarowaniu naszej klasy extendsi wpisać nazwę klasy nadrzędnej. Zwykle wygląda to tak:

class Потомок extends Родитель

Tę konstrukcję należy napisać deklarując klasę Descendant. Nawiasem mówiąc, możesz dziedziczyć tylko z jednej klasy.

Dziedziczenie klas - rozszerza

Na zdjęciu widzimy "krowę" odziedziczoną po "świni". „Świnia” jest dziedziczona z „kurczaka”, „kurczak” z „jajka”. Tylko jeden rodzic! Takie dziedziczenie nie zawsze jest logiczne. Ale jeśli jest tylko świnia, a krowa jest bardzo potrzebna, programista często nie może oprzeć się chęci zrobienia „krowy” ze „świni”.

W Javie nie ma wielokrotnego dziedziczenia: nie można dziedziczyć klasy z dwóch klas. Każda klasa może mieć tylko jedną klasę nadrzędną. Jeśli klasa nadrzędna nie jest określona, ​​przyjmuje się, że klasą nadrzędną jest Object.

Chociaż Java ma wielokrotne dziedziczenie interfejsów. To nieznacznie zmniejsza nasilenie problemu. O interfejsach porozmawiamy nieco później, ale na razie zajmijmy się dziedziczeniem.

PS

Oto kilka historii dla Ciebie o tym, jak często musisz zrobić świnię z muchy. A co się dzieje z tym: