„Hallo Amigo! Wir haben ein faszinierendes neues Thema.“

„Heute gibt es nur faszinierenden Themen!“

„Naja, danke!“

„Keine Ursache.“

„Erinnerst du dich, als wir die ChessItem-Basisklasse eingeführt haben, um alle Klassen für Schachfiguren zu vereinfachen?“

„Ja.“

„Stell dir nun einmal vor, dass jede Figur eine Methode besitzt, die das Anzeigen der Figur auf dem Bildschirm übernimmt. Du rufst die Methode auf und die Figur stellt sich selbst an seinen aktuellen Koordinaten dar. Wäre es sinnvoll, diese Methode in die Basisklasse zu verschieben?“

„Ja.“ Nachdem ich die Polymorphie kennengelernt habe, wäre ich in der Lage, die Anzeigemethode für alle Figuren, unabhängig von ihrem Typ, aufzurufen. So etwa:“

Zum Beispiel:
class ChessBoard
{
  public void drawAllChessItems()
  {
  //draw them regardless of their type.
  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();
  }
 }
}

„Gut gemacht. Genau. Und was würde die Anzeigemethode der ChessItem-Klasse selbst tun?“

„Ich weiß es nicht. Eine solche Figur gibt es nicht. Und das bedeutet, dass sie keine visuelle Darstellung hat.“

„Genau. Und es hat keinen Sinn, ein ChessItem-Objekt zu erstellen. Es gibt keine solche Schachfigur. Es ist nur eine Abstraktion – eine Klasse, die wir aus praktischen Gründen erstellt haben. So funktioniert die Abstraktion der OOP: Wir haben alle wichtigen (von allen Figuren geteilten) Daten und Methoden in eine Basisklasse verschoben, aber wir haben ihre Unterschiede in den Klassen, die bestimmten Schachfiguren entsprechen, behalten.“

Abstrakte Klassen - 1

Java bietet dafür einen speziellen Klassentyp: die abstrakte Klasse. Drei Dinge muss man sich über abstrakte Klassen merken.

1) Eine abstrakte Klasse kann Methoden deklarieren, ohne sie zu implementieren. Eine solche Methode wird als abstrakte Methode bezeichnet.

Zum Beispiel:
 public abstract class ChessItem
{
 public int x, y; //coordinates
 private int value; //the piece's "value"

 public int getValue() //an ordinary method, returns value
 {
   return value;
 }

 public abstract void draw(); //abstract method. There is no implementation.

}

2) Eine abstrakte Methode wird mit dem Stichwort abstract gekennzeichnet.

Wenn eine Klasse auch nur eine abstrakte Methode enthält, dann wird die Klasse auch mit abstract gekennzeichnet.

3) Du kannst keine Objekte einer abstrakten Klasse erstellen. Code, der dies versucht, lässt sich einfach nicht kompilieren.

Java-Code Beschreibung
ChessItem item = new ChessItem();
item.draw();
Dieser Code lässt sich nicht kompilieren.
ChessItem item = new Queen();
item.draw();
Aber du kannst das.

4) Wenn deine Klasse von einer abstrakten Klasse erbt, musst du alle geerbten abstrakten Methoden überschreiben, d.h. du musst sie implementieren. Andernfalls muss deine Klasse ebenfalls als abstract deklariert werden. Wenn die Klasse auch nur eine nicht implementierte Methode enthält, die direkt in der Klasse deklariert oder von der Elternklasse geerbt wurde, dann wird die Klasse als abstrakt betrachtet.

„Aber warum ist all das nötig? Warum brauchen wir abstrakte Klassen? Können wir stattdessen nicht gewöhnliche Klassen verwenden? Und können wir statt abstrakter Methoden nicht einfach leere Implementierungen erstellen, die aus sich öffnenden und schließenden geschweiften Klammern bestehen?“

„Das könntest du. Aber diese Einschränkungen sind wie der private-Modifikator. Wir verwenden den private-Modifikator, um den direkten Zugriff auf Daten bewusst zu verhindern, damit andere Programmierer und ihre Klassen unsere public-Methoden verwenden.“

Dasselbe gilt für eine abstrakte Klasse. Wer auch immer die Klasse geschrieben hat, möchte nicht, dass jemand Instanzen der Klasse erstellt. Im Gegenteil, der Autor erwartet, dass die abstrakten Methoden seiner abstrakten Klasse vererbt und überschrieben werden.

„Ich verstehe immer noch nicht, warum wir uns das Leben so schwer machen sollten.“

„Der Vorteil dieser Funktion zeigt sich bei großen Projekten. Je mehr Klassen du hast, desto deutlicher musst du ihre Aufgaben voneinander abgrenzen. Du wirst schon bald die Vorteile dieser Vorgehensweise erkennen. Da musst man einfach durch.“