This article is currently in the process of being translated into German (~99% done).
Abstract classes
Abstrakte Klassen sind speziell, denn sie können keine Instanzen bilden. Stattdessen vererben sie typischerweise ihre Basisfunktionalität einer neuen Klasse. Aus diesem Grund bilden sie üblicherweise die Basisklasse einer größeren Klassenhierachie. Im Kapitel über Vererbung erzeugten wir eine Animal(Tier)- Klasse und anschließend eine Dog(Hunde)-Klasse, die ihre Eigenschaften von der Animal(Tier)-Klasse erbt. In unserem Projekt könntest du genauso gut entscheiden, dass niemand in der Lage sein sollte, eine Instanz der Animal(Tier)-Klasse zu erzeugen, weil sie zu unspezifisch ist, stattdessen soll eine bestimmte Klasse ihre Eigenschaften erben. Die Animal(Tier)-Klasse dient als Basisklasse für unsere kleine Tiersammlung.
Eine Methode kann ebenfalls als abstrakt definiert werden. Sobald du eine Funktion als abstrakt definiert hast, muss die enthaltende Klasse ebenfalls als abstrakt definiert werden - nur abstrakte Klassen können abstrakte Funktionen enthalten. Eine weitere Folge ist, dass du keinen Code für diese Funktion schreiben brauchst (nicht einmal kannst) - es ist nur eine Deklaration. Das machst du, um alle, die diese abstrakte Klasse erben, zu zwingen, diese Funktion zu implementieren und geeigneten Code dafür zu schreiben. Wenn nicht, wird PHP einen Fehler erzeugen. Abstrakte Klassen können jedoch nicht-abstrakte Methoden enthalten, was dir erlaubt, eine Basisfunktionalität zu implementieren. Lass uns mit einem Beispiel fortfahren. Hier ist die abstrakte Klasse:
abstract class Animal
{
public $name;
public $age;
public function Describe()
{
return $this->name . ", " . $this->age . " years old";
}
abstract public function Greet();
}
Wie du sehen kannst, sieht die Klasse wie eine reguläre Ausnahme aus, mit einigen Unterschieden. Die erste ist das Schlüsselwort "abstract", das verwendet wird, um sowohl die Klasse als auch die letzte Funktion zu kennzeichnen. Wie bereits erwähnt kann eine abstrakte Funktion keinen Code im Ausführungsabschnitt enthalten, daher endet die Definition einfach mit einem Strichpunkt. Nun lass uns eine Klasse erzeugen, die unsere Animal(Tier)-Klasse beerben kann.
class Dog extends Animal
{
public function Greet()
{
return "Woof!";
}
public function Describe()
{
return parent::Describe() . ", and I'm a dog!";
}
}
Wie du sehen kannst, definieren wir beide Funktionen aus der Animal(Tier)-Klasse. Die Greet()-Funktion mussten wir implementieren, weil sie als abstrakt definiert ist - sie liefert einfach ein Geräusch, das für das erzeugte Tier typisch ist. Wir müssen die Describe()-Funktion nicht unbedingt definieren, sie ist bereits in der Animal(Tier)-Klasse implementiert, aber wir wollen die Funktionalität ein wenig erweitern. Wir können den Code aus der Animal(Tier)-Klasse wieder verwenden, was ziemlich cool ist, und dann fügen wir hinzu was immer wir wollen. In diesem Fall verwenden wir das parent-Schlüsselwort um die Animal(Tier)-Klasse zu referenzieren und rufen deren Describe()-Funktion auf. Wir fügen etwas Text zum Ergebnis hinzu um klarzustellen, mit welcher Tierart wir es zu tun haben. Nun lass uns diese neue Klasse ausprobieren:
$animal = new Dog();
$animal->name = "Bob";
$animal->age = 7;
echo $animal->Describe();
echo $animal->Greet();
Nichts ungewöhnliches hier. Wir erzeugen eine neue Instanz der Dog(Hunde)-Klasse, legen zwei Eigenschaften fest und rufen die zwei definierten Methoden auf. Wenn diesen Programmcode testest, wirst du sehen, dass die Describe()-Methode wie erwartet eine Kombination der Animal(Tier)- und der Dog(Hunde)-Klasse ist.