Mehrere Traits verwenden
Teil des Abschnitts Objektorientierte Programmierung der PHP-Journey von Coddy. Lektion 52 von 91.
Ein einzelnes Trait ist nützlich, aber die wahre Stärke zeigt sich, wenn du mehrere Traits in einer Klasse kombinierst. PHP ermöglicht es dir, so viele Traits einzubinden, wie du benötigst, sodass deine Klasse gleichzeitig Fähigkeiten aus mehreren Quellen erhält.
Um mehrere Traits zu verwenden, liste sie einfach durch Kommas getrennt nach dem Schlüsselwort use auf:
<?php
trait Timestampable {
public function getTimestamp(): string {
return date('Y-m-d H:i:s');
}
}
trait Identifiable {
private string $id;
public function generateId(): void {
$this->id = uniqid('id_');
}
public function getId(): string {
return $this->id;
}
}
class Post {
use Timestampable, Identifiable;
public function __construct(public string $title) {
$this->generateId();
}
}
$post = new Post("Hello World");
echo $post->getId() . " - " . $post->getTimestamp();
Ausgabe:
id_6789abc123 - 2024-01-15 10:30:00Die Klasse Post verfügt nun über Methoden aus beiden Traits. Jeder Trait trägt seine eigene Funktionalität bei – Timestampable stellt zeitbezogene Methoden bereit, während Identifiable eindeutige IDs verwaltet. Dieser Ansatz hält jeden Trait auf eine einzige Verantwortung fokussiert und macht deinen Code dadurch modularer und wiederverwendbarer.
Was passiert, wenn zwei Traits Methoden mit demselben Namen haben? Das ist eine Konfliktsituation, die wir in der nächsten Lektion untersuchen werden.
Aufgabe
EinfachErstellen wir ein Produktverwaltungssystem, das mehrere Traits kombiniert, um Produkten sowohl Preis- als auch Bestandsfunktionen zu geben. Jeder Trait übernimmt eine einzelne Verantwortung, und deine Produktklasse erhält Funktionalität von beiden.
Du organisierst deinen Code über drei Dateien:
Priceable.php: Erstelle einen Trait namensPriceable, der die Preisfunktionalität übernimmt. Der Trait sollte Folgendes enthalten:- Eine private Eigenschaft
$price(Gleitkommazahl) - Eine Methode
setPrice(float $price), die den Preis speichert - Eine Methode
getPrice(), die den Preis zurückgibt - Eine Methode
getFormattedPrice(), die den Preis als"$[price]"mit 2 Dezimalstellen formatiert zurückgibt
- Eine private Eigenschaft
Stockable.php: Erstelle einen Trait namensStockable, der den Bestand verwaltet. Der Trait sollte Folgendes enthalten:- Eine private Eigenschaft
$stock(Ganzzahl) - Eine Methode
setStock(int $quantity), die die Bestandsmenge speichert - Eine Methode
getStock(), die den aktuellen Bestand zurückgibt - Eine Methode
isInStock(), dietruezurückgibt, wenn der Bestand größer als 0 ist, andernfallsfalse
- Eine private Eigenschaft
main.php: Binde beide Trait-Dateien ein und erstelle eineProduct-Klasse, die sowohl die TraitsPriceableals auchStockableverwendet. Verwende Constructor Promotion, um eine öffentliche Eigenschaft$namezu definieren. Der Konstruktor sollte außerdem einen Preis und eine Bestandsmenge akzeptieren und die Trait-Methoden verwenden, um diese festzulegen.Du erhältst drei Eingaben: einen Produktnamen, einen Preis und eine Bestandsmenge. Erstelle ein Produkt mit diesen Werten und gib vier Zeilen aus:
- Den Produktnamen
- Den formatierten Preis (unter Verwendung von
getFormattedPrice()) - Die Bestandsmenge
"Available", wenn das Produkt auf Lager ist, oder"Out of stock", wenn es nicht auf Lager ist
Dies zeigt, wie mehrere Traits zusammenarbeiten. Deine Product-Klasse erhält von einem Trait Preisfunktionen und von einem anderen die Bestandsverwaltung. Dabei bleibt jeder Verantwortungsbereich sauber getrennt, während beide zu einem voll ausgestatteten Produkt kombiniert werden.
Probier es selbst
<?php
require_once 'Priceable.php';
require_once 'Stockable.php';
// TODO: Erstelle eine Product-Klasse, die sowohl die Priceable- als auch die Stockable-Traits verwendet
// Verwende Constructor Promotion für die öffentliche $name-Eigenschaft
// Der Konstruktor sollte name, price und stock akzeptieren und Trait-Methoden verwenden, um price und stock zu setzen
class Product {
// TODO: Verwende die Traits hier
// TODO: Implementiere den Konstruktor mit Constructor Promotion für $name
// und setze price und stock mit Trait-Methoden
}
// Eingabe lesen
$name = trim(fgets(STDIN));
$price = floatval(trim(fgets(STDIN)));
$stock = intval(trim(fgets(STDIN)));
// TODO: Erstelle eine Product-Instanz mit den Eingabewerten
// TODO: Gib den Produktnamen aus
// TODO: Gib den formatierten Preis mit getFormattedPrice() aus
// TODO: Gib die Lagermenge aus
// TODO: Gib "Available" aus, wenn auf Lager, oder "Out of stock" wenn nicht
?>Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in OOPKlassen vs. ObjekteDas Schlüsselwort $thisMethodenEigenschaftenKonstruktor (__construct)Destruktor (__destruct)Rückblick – Einfacher Taschenrechner4Vererbung
Grundlegende VererbungDas Schlüsselwort parent::MethodenüberschreibungDas Schlüsselwort finalAbstrakte KlassenRückblick – Mitarbeiterhierarchie7Kapselung
Öffentlich, geschützt, privatZugriffsmodifikatoren im DetailGetter und SetterInformationsverbergungKonstruktor-Promotion (8.0)Wiederholung – System zur Verwaltung von Schülerdatensätzen2Namespaces & Autoloading
Einführung in NamespacesDas use-SchlüsselwortPSR-4-Autoloading-StandardComposer-AutoloaderRückblick – Organisiertes Projekt5Schnittstellen & Verträge
Einführung in SchnittstellenSchnittstellen implementierenMehrere Schnittstellen implementierenSchnittstelle vs. abstrakte KlasseTyp-Hinweise mit SchnittstellenRückblick – Formrechner8Magische Methoden
Einführung in magische Methoden__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Objektklonen__serialize & __unserializeRückblick – Benutzerdefinierte Sammlung11Typsystem & Fehlerbehandlung
TypdeklarationenNullable-TypenUnion- & Intersection-TypenException-KlassenBenutzerdefinierte Exception-HierarchieTry, Catch, FinallyRückblick – Formularvalidator14Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen3Klassen-Eigenschaften
Instanz- vs. statische EigenschaftenKonstanten in KlassenStatische Methoden & EigenschaftenPrivate & geschützte EigenschaftenSchreibgeschützte Eigenschaften (PHP 8.1)Zusammenfassung – Bankkonto-Manager6Polymorphie
Methodenüberschreibung erneut betrachtetPolymorphie über SchnittstellenTyp-Hinweise & Union-TypenSpätes statisches BindenRückblick – Zahlungsabwickler9Traits
Einführung in TraitsMehrere Traits verwendenAuflösung von Trait-KonfliktenAbstrakte Methoden in TraitsTraits vs. Vererbung12Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterObserver-MusterStrategy-Muster15Abschließende Herausforderungen
E-Learning-PlattformBankingsystemEntwicklung einer SpielfigurFahrzeugvermietungÜbe selbstständig: Online-PHP-Compiler