1. Clasa de bază comună

Astăzi ne vom bucura de un amestec de subiecte interesante. Vă amintiți când am introdus ChessItemclasa de bază pentru a simplifica toate clasele care reprezintă piesele de șah? Sper că da 🙂

Acum imaginați-vă că fiecare piesă are o draw()metodă care se ocupă de desenarea ei pe ecran. Numiți draw()metoda și piesa se desenează la coordonatele sale curente. Ar fi convenabil să mutați această metodă în clasa de bază.

Dacă draw()metoda a fost în clasa de bază ChessItem, atunci am putea să o suprascriem în clasele de piese și să scriem cod elegant astfel:

class ChessBoard
{
   public void drawAllChessItems()
   {
      // Add the pieces to the list
      ArrayList<ChessItem> items = new ArrayList<ChessItem>();
      items.add(new King());
      items.add(new Queen());
      items.add(new Bishop());

      // Draw them regardless of their type
      for(ChessItem item: items)
      {
         item.draw();
      }
   }
}

Prin introducerea ChessItemclasei de bază, am reușit să simplificăm foarte mult codul: nu este nevoie să apelăm metodele fiecărei clase separat, putem stoca cu ușurință toate obiectele într-o singură colecție etc.

Dar iată o întrebare interesantă: ce ar trebui să deseneze pe ecran draw()metoda declarată direct în ChessItemclasă? La urma urmei, nu există o astfel de piesă în șah, așa că nu există nimic de desenat.

Este exact. În plus, nu are sens să creezi ChessItemobiecte direct. Nu este o piesă de șah, ci mai degrabă doar o abstractizare - o clasă pe care am creat-o pentru confortul nostru. Acesta este modul în care funcționează abstractizarea în POO : mutăm datele și metodele importante (cele partajate de toate piesele) într-o clasă de bază și păstrăm diferențele lor în clase descendente separate.


2. Clase de abstracte

Clasele abstracte

Pentru astfel de situații, Java are un tip special de clasă: clasa abstractă . Ele sunt concepute pentru a face mai ușor pentru programatori să lucreze cu clase similare și pentru a reduce cantitatea de cod duplicat din ele.

Iată trei lucruri de știut despre clasele abstracte.

Metodă fără implementare

O clasă abstractă poate avea o declarație de metodă fără o implementare. Acesta este exact ceea ce face metoda abstractă. Corpul metodei este pur și simplu înlocuit cu un punct și virgulă. Și înainte de numele metodei, scriem cuvântul abstractcheie. Exemplu:

public abstract class ChessItem
{
   public int x, y; // Coordinates
   private int value; // The piece's value
   public int getValue() // Ordinary method that returns value field
   {
      return value;
   }

   public abstract void draw(); // Abstract method. The implementation is missing.
}

Clasa abstracte

Fiecare metodă fără implementare este marcată cu cuvântul cheie abstract. Dacă o clasă are chiar și o singură metodă abstractă, clasa este de asemenea marcată cu cuvântul abstractcheie.

Interzicerea creării de obiecte

Nu puteți crea obiecte dintr-o clasă abstractă . Un astfel de cod pur și simplu nu se va compila.

Cod Descriere
ChessItem item = new ChessItem();
item.draw();
Acest cod nu compilează :
ChessItem item = new Queen();
item.draw();
Dar poți face asta

Moștenirea unei clase abstracte

Dacă clasa dumneavoastră moștenește o clasă abstractă, atunci trebuie să suprascrieți toate metodele abstracte moștenite, adică trebuie să scrieți o implementare pentru ele. În caz contrar, clasa dvs. în sine va trebui, de asemenea, declarată abstractă.

Dacă o clasă are chiar și o singură metodă neimplementată declarată direct în ea sau moștenită de la o clasă părinte, atunci clasa este considerată abstractă.

Și de ce sunt necesare toate acestea? De ce sunt necesare clase abstracte? Nu este posibil să folosiți în schimb cele obișnuite? Și în loc de metode abstracte, nu am putea scrie doar două paranteze goale ca corp de metodă?

Am putea. Dar aceste restricții sunt asemănătoare modificatorului private. Folosim cuvântul cheie privat pentru a preveni în mod deliberat alți programatori să acceseze direct datele și pentru a-i forța să folosească numai metodele noastre publice atunci când își scriu clasele.

La fel este și cu clasele abstracte. Autorul unei clase abstracte nu dorește să fie create obiecte ale clasei. În schimb, autorul se așteaptă ca metodele abstracte să fie moștenite din clasa abstractă și apoi suprascrise.

Avantajul acestei abordări este ușor evident în proiectele mari. Cu cât ai mai multe clase, cu atât mai clar trebuie să le delimitezi rolurile. Veți vedea beneficiile acestei abordări în viitorul apropiat. Fiecare lucru trece prin asta.