1. Gemeenschappelijke basisklasse

Vandaag zullen we genieten van een smorgasbord van interessante onderwerpen. Weet je nog dat we de basisklasse introduceerden om alle klassen die schaakstukken vertegenwoordigen te vereenvoudigen? ChessItemIk hoop het 🙂

Stel je nu voor dat elk stuk een draw()methode heeft om het op het scherm te tekenen. U roept de draw()methode aan en het stuk tekent zichzelf op de huidige coördinaten. Het zou handig zijn om deze methode naar de basisklasse te verplaatsen.

Als de draw()methode zich in de ChessItem-basisklasse bevond, zouden we deze in de stukklassen kunnen overschrijven en elegante code als volgt kunnen schrijven:

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();
      }
   }
}

Door de ChessItembasisklasse te introduceren, konden we de code aanzienlijk vereenvoudigen: het is niet nodig om de methoden van elke klasse afzonderlijk aan te roepen, we kunnen eenvoudig alle objecten in één enkele verzameling opslaan, enz.

Maar hier is een interessante vraag: wat moet de draw()direct in de ChessItemklas gedeclareerde methode op het scherm tekenen? Zo'n stuk bestaat tenslotte niet in het schaakspel, dus er valt niets te tekenen.

Dat klopt precies. Bovendien heeft het geen zin om ChessItemdirect objecten te creëren. Het is geen schaakstuk, maar gewoon een abstractie - een klasse die we voor ons gemak hebben gemaakt. Dit is hoe abstractie werkt in OOP : we verplaatsen belangrijke gegevens en methoden (die gedeeld worden door alle stukken) naar een basisklasse, en houden hun verschillen in afzonderlijke onderliggende klassen.


2. Abstracte lessen

Abstracte lessen

Voor dergelijke situaties heeft Java een speciaal soort klasse: de abstracte klasse . Ze zijn ontworpen om het voor programmeurs gemakkelijker te maken om met vergelijkbare klassen te werken en om de hoeveelheid gedupliceerde code erin te verminderen.

Hier zijn drie dingen die u moet weten over abstracte klassen.

Methode zonder implementatie

Een abstracte klasse kan een methodedeclaratie hebben zonder implementatie. Dit is precies wat de methode abstract maakt. De body van de methode wordt simpelweg vervangen door een puntkomma. En vóór de naam van de methode schrijven we het abstracttrefwoord. Voorbeeld:

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

Abstracte klasse

Elke methode zonder implementatie is gemarkeerd met het abstracte trefwoord. Als een klasse ook maar één abstracte methode heeft, wordt de klasse ook gemarkeerd met het abstracttrefwoord.

Het maken van objecten verbieden

U kunt geen objecten van een abstracte klasse maken . Dergelijke code compileert gewoon niet.

Code Beschrijving
ChessItem item = new ChessItem();
item.draw();
Deze code compileert niet :
ChessItem item = new Queen();
item.draw();
Maar je kunt dit doen

Een abstracte klasse overerven

Als uw klasse een abstracte klasse erft, moet u alle geërfde abstracte methoden overschrijven, dwz u moet er een implementatie voor schrijven. Anders moet je klasse zelf ook abstract verklaard worden.

Als een klasse zelfs maar één niet-geïmplementeerde methode heeft die er rechtstreeks in is gedeclareerd of is geërfd van een bovenliggende klasse, wordt de klasse als abstract beschouwd.

En waarom is dit allemaal nodig? Waarom zijn abstracte klassen nodig? Is het niet mogelijk om in plaats daarvan gewone te gebruiken? En kunnen we in plaats van abstracte methoden niet gewoon twee lege accolades schrijven als de body van de methode?

We konden. Maar deze beperkingen zijn verwant aan de privatemodifier. We gebruiken het private trefwoord om opzettelijk te voorkomen dat andere programmeurs rechtstreeks toegang krijgen tot gegevens en om hen te dwingen alleen onze openbare methoden te gebruiken bij het schrijven van hun klassen.

Hetzelfde geldt voor abstracte klassen. De auteur van een abstracte klasse wil niet dat objecten van de klasse worden gemaakt. In plaats daarvan verwacht de auteur dat abstracte methoden worden geërfd van de abstracte klasse en vervolgens worden overschreven.

Bij grote projecten is het voordeel van deze aanpak direct duidelijk. Hoe meer klassen je hebt, hoe duidelijker je hun rollen moet afbakenen. U zult de voordelen van deze aanpak in de nabije toekomst zien. Alles gaat hier doorheen.