Vererbung ist eines der zentralen Prinzipien der objektorientierten Programmierung. In PHP ermöglicht das Schlüsselwort extends, eine neue Klasse von einer bestehenden abzuleiten. Die abgeleitete Klasse, auch Kindklasse genannt, übernimmt dabei alle öffentlichen und geschützten Eigenschaften sowie Methoden der Elternklasse. Dieses Tutorial erklärt das Grundprinzip der Vererbung, zeigt den Umgang mit Sichtbarkeiten und behandelt das Überschreiben von Methoden sowie den Konstruktoraufruf in Kindklassen.

Am Anfang steht das Grundprinzip: Wie leitet man eine Klasse von einer anderen ab, und was genau wird dabei übernommen?
Grundprinzip der Vererbung
Eine Kindklasse wird mit dem Schlüsselwort extends von einer Elternklasse abgeleitet. Sie erbt automatisch alle Methoden und Eigenschaften, die nicht als private deklariert sind.
<?php
class Tier
{
public string $name;
public function __construct(string $name)
{
$this->name = $name;
}
public function laut(): string
{
return "{$this->name} macht ein Geräusch.";
}
}
class Hund extends Tier
{
/* Hund erbt $name und laut() von Tier */
}
$hund = new Hund('Rex');
echo $hund->laut();
/* Ausgabe: Rex macht ein Geräusch. */
Die Klasse Hund enthält keinen eigenen Code, verfügt aber trotzdem über die Eigenschaft $name und die Methode laut(). PHP verwendet einfache Vererbung, das heißt eine Klasse kann immer nur von genau einer Elternklasse erben.
Das folgende Diagramm veranschaulicht die Beziehung zwischen Elternklasse und Kindklasse.
classDiagram
class Tier {
+name: string
+laut() string
}
class Hund {
}
class Katze {
+schnurren() string
}
Tier <|-- Hund
Tier <|-- Katze
Eigenschaften und Methoden erben
Die Kindklasse kann eigene Methoden und Eigenschaften ergänzen und gleichzeitig alles aus der Elternklasse nutzen. So entsteht eine spezialisierte Variante der ursprünglichen Klasse.
<?php
class Person
{
public function __construct(
protected string $name,
protected int $alter
) {}
public function vorstellen(): string
{
return "Ich bin {$this->name}, {$this->alter} Jahre alt.";
}
}
class Student extends Person
{
public function __construct(
string $name,
int $alter,
private string $fach
) {
parent::__construct($name, $alter);
}
public function studienfach(): string
{
return "{$this->name} studiert {$this->fach}.";
}
}
$student = new Student('Anna', 22, 'Informatik');
echo $student->vorstellen();
/* Ausgabe: Ich bin Anna, 22 Jahre alt. */
echo $student->studienfach();
/* Ausgabe: Anna studiert Informatik. */
Die Klasse Student erbt die Methode vorstellen() und fügt die eigene Methode studienfach() hinzu. Der Aufruf von parent::__construct() stellt sicher, dass die Elternklasse korrekt initialisiert wird.
Sichtbarkeiten: public, protected, private
Die Sichtbarkeit einer Eigenschaft oder Methode bestimmt, ob sie in einer Kindklasse verfügbar ist. Mit public deklarierte Mitglieder sind überall zugänglich. Mit protected deklarierte Mitglieder stehen nur innerhalb der eigenen Klasse und in Kindklassen zur Verfügung. Mit private deklarierte Mitglieder sind ausschließlich in der Klasse selbst nutzbar und werden nicht vererbt.
<?php
class Oberklasse
{
public string $oeffentlich = 'sichtbar';
protected string $geschuetzt = 'nur intern';
private string $privat = 'nicht vererbbar';
public function zeigePrivat(): string
{
return $this->privat;
}
}
class Unterklasse extends Oberklasse
{
public function test(): void
{
echo $this->oeffentlich; /* Funktioniert */
echo $this->geschuetzt; /* Funktioniert */
/* echo $this->privat; Fehler! Nicht zugreifbar */
}
}
$unter = new Unterklasse();
$unter->test();
echo $unter->zeigePrivat();
/* Ausgabe: nicht vererbbar */
Die Methode zeigePrivat() ist public und wird daher vererbt. Über sie kann die Kindklasse indirekt auf die private Eigenschaft zugreifen. Direkt ist $privat in der Unterklasse jedoch nicht erreichbar.
Methoden überschreiben (Overriding)
Eine Kindklasse kann geerbte Methoden neu definieren. Die Methodensignatur muss dabei kompatibel zur Elternklasse bleiben, damit das Liskovsche Substitutionsprinzip eingehalten wird.
<?php
class Fahrzeug
{
public function beschreibung(): string
{
return 'Ein allgemeines Fahrzeug.';
}
}
class Auto extends Fahrzeug
{
public function beschreibung(): string
{
return 'Ein Auto mit vier Rädern.';
}
}
class Motorrad extends Fahrzeug
{
public function beschreibung(): string
{
return parent::beschreibung() . ' Genauer: ein Motorrad.';
}
}
$auto = new Auto();
echo $auto->beschreibung();
/* Ausgabe: Ein Auto mit vier Rädern. */
$motorrad = new Motorrad();
echo $motorrad->beschreibung();
/* Ausgabe: Ein allgemeines Fahrzeug. Genauer: ein Motorrad. */
Die Klasse Auto ersetzt die Methode vollständig, während Motorrad mit parent::beschreibung() die Version der Elternklasse aufruft und das Ergebnis erweitert. So lassen sich bestehende Funktionalitäten gezielt anpassen oder ergänzen.
Konstruktor und parent::__construct()
Definiert eine Kindklasse einen eigenen Konstruktor, wird der Konstruktor der Elternklasse nicht automatisch aufgerufen. Der explizite Aufruf von parent::__construct() ist notwendig, damit alle Eigenschaften der Elternklasse korrekt gesetzt werden.
<?php
class Produkt
{
public function __construct(
protected string $bezeichnung,
protected float $preis
) {}
public function info(): string
{
return "{$this->bezeichnung}: {$this->preis} EUR";
}
}
class RabattProdukt extends Produkt
{
public function __construct(
string $bezeichnung,
float $preis,
private int $rabatt
) {
parent::__construct($bezeichnung, $preis);
}
public function rabattPreis(): float
{
return $this->preis * (1 - $this->rabatt / 100);
}
public function info(): string
{
return parent::info() . " ({$this->rabatt}% Rabatt)";
}
}
$artikel = new RabattProdukt('Laptop', 999.00, 10);
echo $artikel->info();
/* Ausgabe: Laptop: 999 EUR (10% Rabatt) */
echo $artikel->rabattPreis();
/* Ausgabe: 899.1 */
Ohne den Aufruf von parent::__construct() würden $bezeichnung und $preis nicht initialisiert, was zu Fehlern bei der späteren Nutzung führen würde.
Warum PHP keine Mehrfachvererbung hat
PHP unterstützt ausschließlich einfache Vererbung. Eine Klasse kann nicht gleichzeitig von zwei Elternklassen erben. Dieses Design vermeidet das sogenannte Diamond Problem, bei dem Konflikte entstehen, wenn zwei Elternklassen dieselbe Methode definieren. Als Alternative bietet PHP seit Version 5.4 Traits an. Traits ermöglichen die Wiederverwendung von Code in mehreren Klassen, ohne eine Vererbungshierarchie aufzubauen.
Fazit
Vererbung mit extends ist ein mächtiges Werkzeug der objektorientierten Programmierung in PHP. Eine Kindklasse erbt alle public und protected Mitglieder der Elternklasse, kann eigene Methoden ergänzen und geerbte Methoden überschreiben. Der Aufruf von parent::__construct() stellt die korrekte Initialisierung sicher. Die drei Sichtbarkeiten public, protected und private steuern den Zugriff in der Vererbungshierarchie. Da PHP nur einfache Vererbung unterstützt, stehen Traits für die Wiederverwendung von Code über Klassengrenzen hinweg zur Verfügung.