Menu
Coddy logo textTech

Traits vs. Vererbung

Teil des Abschnitts Objektorientierte Programmierung der PHP-Journey von Coddy. Lektion 55 von 91.

Nachdem du nun verstanden hast, wie Traits funktionieren, klären wir, wann du Traits und wann du Vererbung verwenden solltest. Beide ermöglichen die Wiederverwendung von Code, dienen jedoch unterschiedlichen Zwecken und haben verschiedene Eigenschaften.

Vererbung stellt eine „ist-ein“-Beziehung her. Eine Dog-Klasse, die Animal erweitert, bedeutet, dass ein Hund ein Tier ist. Die Kindklasse erbt die Identität des Elternteils und kann überall dort verwendet werden, wo der übergeordnete Typ erwartet wird.

Traits stellen eine „has-a“-Fähigkeit bereit. Wenn eine Klasse ein Loggable-Trait verwendet, verfügt sie über Protokollierungsfunktionen – aber sie wird dadurch nicht zu einem Logger. Traits fügen Verhalten hinzu, ohne zu verändern, was die Klasse grundlegend ist.

<?php
// Vererbung: Dog IST ein Animal
class Animal {
    public function breathe(): void {
        echo "Breathing";
    }
}

class Dog extends Animal {
    public function bark(): void {
        echo "Woof!";
    }
}

// Trait: Dog HAT Logging-Fähigkeit
trait Loggable {
    public function log(string $msg): void {
        echo "Log: $msg";
    }
}

class Cat extends Animal {
    use Loggable;
}

Wichtige Unterschiede, die du dir merken solltest:

AspektVererbungTraits
Beziehungist-einverfügt über eine Fähigkeit
LimitierungNur ein übergeordnetes ElementMehrere Traits erlaubt
TypprüfungFunktioniert mit instanceofKeine Typidentität
Am besten geeignet fürHierarchische BeziehungenGemeinsame Verhaltensweisen über nicht verwandte Klassen hinweg

Verwende Vererbung, wenn Klassen eine gemeinsame Identität haben. Verwende Traits, wenn voneinander unabhängige Klassen dieselbe Funktionalität benötigen, ohne Teil desselben Stammbaums zu sein.

challenge icon

Aufgabe

Einfach

Erstellen wir ein Fahrzeugsystem, das veranschaulicht, wann Vererbung und wann Traits verwendet werden sollten. Du erstellst eine Hierarchie von Fahrzeugen, die durch Vererbung eine gemeinsame Identität teilen, während Traits übergreifende Fähigkeiten hinzufügen.

Du organisierst deinen Code über vier Dateien:

  • Trackable.php: Erstelle ein Trait namens Trackable, das GPS-Ortung bereitstellt. Das Trait sollte Folgendes enthalten:
    • Eine private Eigenschaft $location (String)
    • Eine Methode setLocation(string $location), die den aktuellen Standort speichert
    • Eine Methode getLocation(), die "Location: [location]" zurückgibt
    Dieses Trait stellt eine „has-a“-Fähigkeit dar: Jedes Fahrzeug kann Ortung haben, aber Ortung zu haben macht etwas nicht zu einem Fahrzeug.
  • Vehicle.php: Erstelle eine Basisklasse Vehicle, die die „is-a“-Beziehung festlegt. Binde die Trait-Datei ein. Verwende Constructor Promotion, um eine geschützte Eigenschaft $brand zu definieren. Füge eine Methode describe() hinzu, die "Vehicle: [brand]" zurückgibt. Diese Klasse sollte das Trait Trackable verwenden, da alle Fahrzeuge in unserer Flotte über GPS verfügen werden.
  • Car.php: Erstelle eine Klasse Car, die von Vehicle erbt. Binde die Vehicle-Datei ein. Verwende Constructor Promotion, um die Marke und eine private Eigenschaft $doors (Ganzzahl) zu übernehmen. Rufe den Konstruktor der Elternklasse mit der Marke auf. Überschreibe die Methode describe(), sodass sie "Car: [brand] with [doors] doors" zurückgibt.
  • main.php: Binde die Car-Datei ein. Du erhältst drei Eingaben: einen Markennamen, eine Anzahl von Türen und eine Standortzeichenkette. Erstelle eine Instanz von Car, setze ihren Standort und gib anschließend zwei Zeilen aus:
    • Das Ergebnis des Aufrufs von describe()
    • Das Ergebnis des Aufrufs von getLocation()

Beachte, wie Vererbung und Traits hier zusammenwirken: Car ist ein Vehicle (Vererbung legt die Identität fest), während Vehicle Ortungsfunktionalität hat (das Trait fügt Verhalten hinzu). Du könntest instanceof Vehicle verwenden, um zu prüfen, ob etwas ein Fahrzeug ist, aber es gibt keinen Typ „Trackable“, gegen den du prüfen könntest: Das ist der entscheidende Unterschied zwischen diesen beiden Ansätzen.

Probier es selbst

<?php
// Hauptdatei - Car-Instanz erstellen und testen

// TODO: Die Datei Car.php einbinden

// Eingaben lesen
$brand = trim(fgets(STDIN));
$doors = intval(trim(fgets(STDIN)));
$location = trim(fgets(STDIN));

// TODO: Eine Car-Instanz mit brand und doors erstellen

// TODO: Den Standort des Autos setzen

// TODO: Das Ergebnis von describe() ausgeben

// TODO: Das Ergebnis von getLocation() ausgeben
?>
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-PHP-Compiler