Konfliktlösung bei Traits
Teil des Abschnitts Objektorientierte Programmierung der PHP-Journey von Coddy — Lektion 53 von 91.
Wenn zwei Traits Methoden mit demselben Namen definieren, wirft PHP einen fatalen Fehler. Sie müssen PHP explizit mitteilen, wie dieser Konflikt zu handhaben ist, indem Sie die Operatoren insteadof und as verwenden.
<?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 insteadof-Operator wählt aus, welche Methode eines Traits verwendet werden soll, wenn ein Konflikt besteht. In diesem Beispiel gewinnt FileLogger::log und wird zur Standard-log()-Methode. Der as-Operator erstellt einen Alias, mit dem Sie auf die Methode des anderen Traits unter einem anderen Namen zugreifen können.
Sie können auch as verwenden, um die Sichtbarkeit einer Methode zu ändern:
<?php
trait Greeting {
public function sayHello(): void {
echo "Hello!";
}
}
class Person {
use Greeting {
sayHello as private;
}
}
Dies macht sayHello() innerhalb der Person-Klasse privat, obwohl sie im Trait public ist. Die Konfliktauflösung bietet Ihnen eine feingranulare Kontrolle darüber, wie Trait-Methoden in Ihre Klassen integriert werden.
Aufgabe
EinfachLassen Sie uns ein Benachrichtigungssystem erstellen, bei dem verschiedene Kanäle Nachrichten senden können. Dabei müssen wir Konflikte lösen, wenn mehrere Traits denselben Methodennamen bereitstellen.
Sie werden Ihren Code über vier Dateien organisieren:
EmailNotifier.php— Erstellen Sie einen Trait namensEmailNotifiermit einer Methodenotify(string $message), die"Email: [message]"zurückgibt.SmsNotifier.php— Erstellen Sie einen Trait namensSmsNotifiermit einer Methodenotify(string $message), die"SMS: [message]"zurückgibt.AlertService.php— Erstellen Sie eine KlasseAlertService, die beide Traits verwendet. Da beide Traits einenotify()-Methode haben, müssen Sie diesen Konflikt lösen:- Verwenden Sie
EmailNotifier::notifyals Standard-notify()-Methode - Erstellen Sie einen Alias
notifyBySmsfür die MethodeSmsNotifier::notify
notifyAll(string $message)hinzu, die beide Benachrichtigungsmethoden aufruft und diese kombiniert auf separaten Zeilen zurückgibt.- Verwenden Sie
main.php— Binden Sie alle erforderlichen Dateien ein und erstellen Sie eineAlertService-Instanz. Sie erhalten eine Eingabe: einen Nachrichten-String. Geben Sie 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 zeigt, wie insteadof entscheidet, welche Methode eines Traits bei einem Namenskonflikt gewinnt, während as es Ihnen ermöglicht, den Zugriff auf die Methode des anderen Traits unter einem anderen Namen beizubehalten.
Spickzettel
Wenn mehrere Traits Methoden mit demselben Namen definieren, erfordert PHP eine explizite Konfliktlösung unter Verwendung der Operatoren insteadof und as.
Der Operator insteadof legt fest, welche Methode eines Traits standardmäßig verwendet 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"); // File: Error occurred
$app->logToDatabase("Error occurred"); // DB: Error occurred
Der Operator as erstellt einen Alias für eine Trait-Methode und ermöglicht so den Zugriff unter einem anderen Namen.
Sie können 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;
}
}
Probier es selbst
<?php
require_once 'AlertService.php';
// Eingabe lesen
$message = trim(fgets(STDIN));
// TODO: Eine AlertService-Instanz erstellen
// TODO: Das Ergebnis des Aufrufs von notify() mit der Nachricht ausgeben
// TODO: Das Ergebnis des Aufrufs von notifyBySms() mit der Nachricht ausgeben
// TODO: Das Ergebnis des Aufrufs von notifyAll() mit der Nachricht ausgeben
?>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 die OOPKlassen vs. ObjekteDas $this-SchlüsselwortMethodenEigenschaftenKonstruktor (__construct)Destruktor (__destruct)Rückblick - Einfacher Taschenrechner4Vererbung
Grundlagen der VererbungDas parent:: SchlüsselwortMethoden überschreibenDas final SchlüsselwortAbstrakte KlassenZusammenfassung – Mitarbeiter-Hierarchie7Kapselung
Public, Protected, PrivateZugriffsmodifikatoren im DetailGetter und SetterInformation HidingConstructor Promotion (8.0)Zusammenfassung – Studentenverwaltungssystem2Namensräume & Autoloading
Einführung in NamensräumeDas use-SchlüsselwortPSR-4 Autoloading-StandardComposer AutoloaderZusammenfassung – Organisiertes Projekt5Interfaces & Verträge
Einführung in InterfacesInterfaces implementierenMehrfache Interface-ImplementierungInterface vs. Abstrakte KlasseType Hinting mit InterfacesZusammenfassung – Formen-Rechner8Magische Methoden
Einführung in magische Methoden__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Objekt-Klonen__serialize & __unserializeZusammenfassung - Eigene Collection11Typsystem & Fehlerbehandlung
TypdeklarationenNullable-TypenUnion- & Intersection-TypenException-KlassenEigene Exception-HierarchieTry, Catch, FinallyZusammenfassung - Formular-Validator14Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen3Klasseneigenschaften
Instanz- vs. statische EigenschaftenKonstanten in KlassenStatische Methoden & EigenschaftenPrivate & geschützte EigenschaftenReadonly-Eigenschaften (PHP 8.1)Zusammenfassung – Bankkonto-Manager6Polymorphismus
Method Overriding erneut betrachtetPolymorphismus über InterfacesType Hinting & Union TypesLate Static BindingZusammenfassung – Payment Processor9Traits
Einführung in TraitsVerwendung mehrerer TraitsKonfliktlösung bei TraitsAbstrakte Methoden in TraitsTraits vs. Vererbung12Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterObserver-MusterStrategy-Muster15Abschlussherausforderungen
E-Learning-PlattformBanksystemSpielcharakter-EntwicklungFahrzeugvermietung