W3docs

PHP OOP Vererbung

Vererbung in PHP OOP mit extends, parent::, Methodenüberschreibung und final – vollständige Erklärung mit Beispielen.

Vererbung erlaubt es einer Klasse, die Eigenschaften und Methoden einer anderen wiederzuverwenden, sodass man „ist-ein"-Beziehungen modellieren kann (ein Car ist ein Vehicle), ohne Code zu duplizieren. In PHP wird dies mit dem Schlüsselwort extends umgesetzt. Dieses Kapitel behandelt die Syntax, wie Methodenüberschreibung und das Schlüsselwort parent funktionieren, wie Konstruktoren vererbt werden, die Rolle von Sichtbarkeit und dem Schlüsselwort final sowie ein vollständiges, ausführbares Beispiel zum Ausprobieren.

Falls du noch keine Erfahrung mit Klassen hast, beginne mit PHP Klassen und Objekte und komm dann hierher zurück.

Was ist Vererbung?

Vererbung ist die Fähigkeit, eine neue Klasse (das Kind, die Unterklasse oder abgeleitete Klasse) auf Basis einer bestehenden (dem Elternteil, der Oberklasse oder Basisklasse) zu definieren. Das Kind erhält automatisch die public- und protected-Member des Elternteils und kann:

  • sie wiederverwenden wie sie sind,
  • sie mit einer eigenen Implementierung überschreiben, oder
  • völlig neue Eigenschaften und Methoden hinzufügen.

PHP unterstützt nur einfache Vererbung: Eine Klasse kann genau ein Elternteil erweitern. Man kann jedoch eine Kette aufbauen — Hatchback extends Car extends Vehicle — und eine Klasse kann zusätzlich viele Interfaces implementieren, wenn Verhalten aus mehr als einer Quelle benötigt wird.

Vorteile der Vererbung

  • Wiederverwendbarkeit — gemeinsame Logik liegt im Elternteil, wird also nur einmal geschrieben.
  • Wartbarkeit — eine Korrektur im Elternteil wirkt sich auf jede Unterklasse aus; weniger Duplikation bedeutet weniger Stellen für Fehler.
  • Polymorphismus — Code, der ein Vehicle erwartet, funktioniert mit jeder Unterklasse, sodass Implementierungen frei ausgetauscht werden können.
  • Klare Modellierung — die Klassenhierarchie dokumentiert die „ist-ein"-Beziehungen in der Domäne.

PHP OOP Vererbungs-Syntax

Um eine Unterklasse zu erstellen, schreibt man extends gefolgt vom Namen der Elternklasse:

class ChildClass extends ParentClass {
    // child-specific properties and methods
}

ChildClass hat nun alle public- und protected-Member von ParentClass. Beachte, dass private-Member des Elternteils vom Kind nicht zugänglich sind — verwende protected, wenn Unterklassen auf einen Member zugreifen, er aber von außen verborgen bleiben soll. Siehe PHP Zugriffsmodifikatoren für die vollständigen Sichtbarkeitsregeln.

Elternmethoden überschreiben

Eine Unterklasse überschreibt eine Elternmethode, indem sie eine Methode mit demselben Namen deklariert. Die Version des Kindes ersetzt die des Elternteils für Objekte dieser Unterklasse:

class ParentClass {
    public function displayMessage() {
        echo "Hello from ParentClass";
    }
}

class ChildClass extends ParentClass {
    public function displayMessage() {
        echo "Hello from ChildClass";
    }
}

Die Elternmethode mit parent:: aufrufen

Überschreiben bedeutet nicht zwangsläufig Ersetzen — oft möchte man das Verhalten des Elternteils erweitern. Mit parent:: ruft man zuerst die Version des Elternteils auf und ergänzt sie dann:

class ChildClass extends ParentClass {
    public function displayMessage() {
        parent::displayMessage(); // runs the parent's logic
        echo " — and hello from ChildClass";
    }
}

Das Hinzufügen des Attributs #[\Override] (PHP 8.3+) über einer Methode weist PHP an, einen Fehler auszulösen, wenn die Methode tatsächlich keine Elternmethode überschreibt — eine günstige Möglichkeit, Tippfehler in Methodennamen aufzudecken.

Konstruktoren erben und erweitern

Wenn eine Kindklasse keinen eigenen Konstruktor definiert, wird der Elternkonstruktor geerbt und läuft automatisch. Wenn das Kind jedoch einen eigenen definiert, wird der Elternkonstruktor nicht automatisch aufgerufen — du musst ihn explizit mit parent::__construct(...) aufrufen:

class Vehicle {
    public function __construct(public string $make) {}
}

class Car extends Vehicle {
    public function __construct(string $make, public string $fuelType) {
        parent::__construct($make); // initialise the inherited part
    }
}

Weitere Informationen zu Konstruktoren findest du unter PHP Konstruktor.

Überschreiben mit final verhindern

Markiere eine Methode mit final, um zu verhindern, dass Unterklassen sie überschreiben, oder markiere eine ganze Klasse als final, um ihre Erweiterung zu unterbinden:

class PaymentBase {
    final public function transactionId(): string {
        return 'TX-' . uniqid();
    }
}

Dies ist nützlich für Logik, die überall identisch funktionieren muss. Siehe PHP final Schlüsselwort für Details. Wenn das Elternteil die Signatur einer Methode definieren, aber jedes Kind dazu zwingen soll, den Rumpf zu implementieren, verwende stattdessen eine abstrakte Klasse.

PHP OOP Vererbungs-Beispiel

Hier ist ein vollständiges, ausführbares Programm. Eine Basisklasse Vehicle enthält die gemeinsamen Daten, und eine Unterklasse Car fügt eine Eigenschaft fuelType hinzu und erweitert displayDetails() via parent:::

<?php

class Vehicle
{
    public function __construct(
        protected string $make,
        protected string $model,
        protected int $year
    ) {}

    public function displayDetails(): void
    {
        echo "Make: {$this->make}\n";
        echo "Model: {$this->model}\n";
        echo "Year: {$this->year}\n";
    }
}

class Car extends Vehicle
{
    public function __construct(
        string $make,
        string $model,
        int $year,
        protected string $fuelType
    ) {
        parent::__construct($make, $model, $year);
    }

    public function displayDetails(): void
    {
        parent::displayDetails();           // reuse the parent's output
        echo "Fuel Type: {$this->fuelType}\n"; // then add our own
    }
}

$car = new Car('Toyota', 'Corolla', 2023, 'Hybrid');
$car->displayDetails();

Ausgabe:

Make: Toyota
Model: Corolla
Year: 2023
Fuel Type: Hybrid

Car erbt make, model und year (als protected deklariert, damit die Unterklasse sie nutzen kann), verwendet displayDetails() des Elternteils über parent:: wieder und fügt eine eigene Zeile für fuelType hinzu.

Häufige Fallstricke

  • private wird nicht vererbt. Eine private-Eigenschaft des Elternteils ist für das Kind unsichtbar. Verwende protected, wenn Unterklassen darauf zugreifen müssen.
  • Konstruktoren werden nicht automatisch weitergereicht, wenn das Kind einen eigenen definiert — rufe parent::__construct() immer selbst auf.
  • PHP hat keine Mehrfachvererbung. Eine Klasse erweitert ein Elternteil; nutze Interfaces oder Traits, um Verhalten aus mehreren Quellen zu teilen.
  • Überschreibungsfehler werden vor PHP 8.3 stillschweigend ignoriert — ein falsch geschriebener Methodenname erstellt einfach eine neue Methode anstatt zu überschreiben. Füge #[\Override] zur Sicherheit hinzu.

Fazit

Vererbung erlaubt einer Unterklasse, die Member einer Elternklasse über das Schlüsselwort extends wiederzuverwenden, zu überschreiben und zu erweitern, wobei parent:: Zugriff auf die ursprüngliche Implementierung gewährt. Kombiniert mit Sichtbarkeitsmodifikatoren, Konstruktoren und final ist sie das Rückgrat der Codewiederverwendung und des Polymorphismus in PHP OOP. Erkunde als nächstes abstrakte Klassen und Interfaces, um sauberere Klassenhierarchien zu entwerfen.

Übungen

Übung
Welche der folgenden Aussagen zur PHP-Vererbung sind korrekt?
Welche der folgenden Aussagen zur PHP-Vererbung sind korrekt?
Was this page helpful?