1. Gemeinsame Basisklasse

Heute erwartet uns ein Sammelsurium an interessanten Themen. Erinnern Sie sich, als wir die ChessItemBasisklasse eingeführt haben, um alle Klassen zu vereinfachen, die Schachfiguren darstellen? Ich hoffe es 🙂

Stellen Sie sich nun vor, dass jedes Stück über eine draw()Methode verfügt, mit der es auf dem Bildschirm gezeichnet wird. Sie rufen die draw()Methode auf und das Stück zeichnet sich selbst an seinen aktuellen Koordinaten. Es wäre praktisch, diese Methode in die Basisklasse zu verschieben.

Wenn sich die draw()Methode in der Basisklasse ChessItem befände, könnten wir sie in den Figurenklassen überschreiben und eleganten Code wie diesen schreiben:

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

Durch die Einführung der ChessItemBasisklasse konnten wir den Code erheblich vereinfachen: Es ist nicht erforderlich, die Methoden jeder Klasse separat aufzurufen, wir können alle Objekte problemlos in einer einzigen Sammlung speichern usw.

Aber hier ist eine interessante Frage: Was soll die draw()direkt in der ChessItemKlasse deklarierte Methode auf dem Bildschirm zeichnen? Schließlich gibt es im Schach keine solche Figur, also gibt es auch nichts zu zeichnen.

Das ist genau richtig. Darüber hinaus macht es keinen Sinn, ChessItemObjekte direkt zu erstellen. Es handelt sich nicht um eine Schachfigur, sondern lediglich um eine Abstraktion – eine Klasse, die wir zu unserer Bequemlichkeit erstellt haben. So funktioniert Abstraktion in OOP : Wir verschieben wichtige Daten und Methoden (die von allen Teilen gemeinsam genutzt werden) in eine Basisklasse und behalten ihre Unterschiede in separaten Nachkommenklassen bei.


2. Abstrakte Klassen

Abstrakte Klassen

Für solche Situationen gibt es in Java eine spezielle Klasse: die abstrakte Klasse . Sie sollen Programmierern die Arbeit mit ähnlichen Klassen erleichtern und die Menge des darin enthaltenen doppelten Codes reduzieren.

Hier sind drei Dinge, die Sie über abstrakte Klassen wissen sollten.

Methode ohne Implementierung

Eine abstrakte Klasse kann eine Methodendeklaration ohne Implementierung haben. Genau das macht die Methode abstrakt. Der Methodenkörper wird einfach durch ein Semikolon ersetzt. Und vor den Namen der Methode schreiben wir das abstractSchlüsselwort. Beispiel:

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

Abstrakte Klasse

Jede Methode ohne Implementierung wird mit dem Schlüsselwort abstract gekennzeichnet. Wenn eine Klasse auch nur eine abstrakte Methode hat, wird die Klasse auch mit dem Schlüsselwort gekennzeichnet abstract.

Verbot der Erstellung von Objekten

Sie können keine Objekte einer abstrakten Klasse erstellen . Ein solcher Code lässt sich einfach nicht kompilieren.

Code Beschreibung
ChessItem item = new ChessItem();
item.draw();
Dieser Code lässt sich nicht kompilieren :
ChessItem item = new Queen();
item.draw();
Aber Sie können dies tun

Eine abstrakte Klasse erben

Wenn Ihre Klasse eine abstrakte Klasse erbt, müssen Sie alle geerbten abstrakten Methoden überschreiben, dh Sie müssen eine Implementierung für sie schreiben. Andernfalls muss auch Ihre Klasse selbst als abstrakt deklariert werden.

Wenn in einer Klasse auch nur eine nicht implementierte Methode direkt deklariert oder von einer übergeordneten Klasse geerbt ist, gilt die Klasse als abstrakt.

Und warum ist das alles notwendig? Warum werden abstrakte Klassen benötigt? Ist es nicht möglich, stattdessen normale zu verwenden? Und könnten wir statt abstrakter Methoden nicht einfach zwei leere geschweifte Klammern als Methodenkörper schreiben?

Wir konnten. Aber diese Einschränkungen ähneln dem privateModifikator. Wir verwenden das Schlüsselwort private, um andere Programmierer bewusst am direkten Zugriff auf Daten zu hindern und sie zu zwingen, beim Schreiben ihrer Klassen nur unsere öffentlichen Methoden zu verwenden.

Dasselbe gilt auch für abstrakte Klassen. Der Autor einer abstrakten Klasse möchte nicht, dass Objekte der Klasse erstellt werden. Stattdessen erwartet der Autor, dass abstrakte Methoden von der abstrakten Klasse geerbt und dann überschrieben werden.

Der Vorteil dieses Ansatzes zeigt sich deutlich bei großen Projekten. Je mehr Klassen Sie haben, desto klarer müssen Sie deren Rollen abgrenzen. Sie werden den Nutzen dieses Ansatzes in naher Zukunft sehen. Alles geht dadurch durch.