Auflösung von Trait-Konflikten
Teil des Abschnitts Objektorientierte Programmierung der PHP-Journey von Coddy. Lektion 53 von 91.
Wenn zwei Traits Methoden mit demselben Namen definieren, löst PHP einen schwerwiegenden Fehler aus. Du musst PHP mithilfe der Operatoren insteadof und as ausdrücklich mitteilen, wie dieser Konflikt behandelt werden soll.
<?php
trait FileLogger {
public function log(string $message): void {
echo "File: $message";
}
}
trait DatabaseLogger {
public function log(string $message): void {
echo "DB: $message";
}
}
class Application {
use FileLogger, DatabaseLogger {
FileLogger::log insteadof DatabaseLogger;
DatabaseLogger::log as logToDatabase;
}
}
$app = new Application();
$app->log("Error occurred");
$app->logToDatabase("Error occurred");
Ausgabe:
File: Error occurred
DB: Error occurredDer Operator insteadof legt fest, welche Methode eines Traits bei einem Konflikt verwendet wird. In diesem Beispiel gewinnt FileLogger::log und wird zur standardmäßigen Methode log(). Der Operator as erstellt einen Alias, sodass du auf die Methode des anderen Traits unter einem anderen Namen zugreifen kannst.
Du kannst as auch verwenden, um die Sichtbarkeit einer Methode zu ändern:
<?php
trait Greeting {
public function sayHello(): void {
echo "Hello!";
}
}
class Person {
use Greeting {
sayHello as private;
}
}
Dadurch wird sayHello() innerhalb der Klasse Person privat, obwohl sie im Trait öffentlich ist. Die Konfliktauflösung gibt dir eine präzise Kontrolle darüber, wie Trait-Methoden in deine Klassen integriert werden.
Aufgabe
EinfachErstellen wir ein Benachrichtigungssystem, über das verschiedene Kanäle Nachrichten senden können. Wir müssen jedoch Konflikte lösen, wenn mehrere Traits denselben Methodennamen bereitstellen.
Du wirst deinen Code auf vier Dateien aufteilen:
EmailNotifier.php: Erstelle ein Trait namensEmailNotifiermit einer Methodenotify(string $message), die"Email: [message]"zurückgibt.SmsNotifier.php: Erstelle ein Trait namensSmsNotifiermit einer Methodenotify(string $message), die"SMS: [message]"zurückgibt.AlertService.php: Erstelle eine KlasseAlertService, die beide Traits verwendet. Da beide Traits über eine Methodenotify()verfügen, musst du diesen Konflikt lösen:- Verwende
EmailNotifier::notifyals standardmäßigenotify()-Methode - Erstelle für die Methode
SmsNotifier::notifyein AliasnotifyBySms
notifyAll(string $message)hinzu, die beide Benachrichtigungsmethoden aufruft und ihre Ergebnisse in separaten Zeilen kombiniert zurückgibt.- Verwende
main.php: Binde alle erforderlichen Dateien ein und erstelle eine Instanz vonAlertService. Du erhältst eine Eingabe: eine Nachrichtenzeichenfolge. Gib drei Zeilen aus:- Das Ergebnis des Aufrufs von
notify()mit der Nachricht - Das Ergebnis des Aufrufs von
notifyBySms()mit der Nachricht - Das Ergebnis des Aufrufs von
notifyAll()mit der Nachricht
- Das Ergebnis des Aufrufs von
Dies veranschaulicht, wie insteadof festlegt, welche Trait-Methode bei einem Namenskonflikt verwendet wird, während as dir ermöglicht, weiterhin über einen anderen Namen auf die Methode des anderen Traits zuzugreifen.
Probier es selbst
<?php
require_once 'AlertService.php';
// Eingabe lesen
$message = trim(fgets(STDIN));
// TODO: Erstelle eine AlertService-Instanz
// TODO: Gib das Ergebnis des Aufrufs von notify() mit der Nachricht aus
// TODO: Gib das Ergebnis des Aufrufs von notifyBySms() mit der Nachricht aus
// TODO: Gib das Ergebnis des Aufrufs von notifyAll() mit der Nachricht aus
?>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