Menu
Coddy logo textTech

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 occurred

Der 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.

challenge icon

Aufgabe

Einfach

Erstellen 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 namens EmailNotifier mit einer Methode notify(string $message), die "Email: [message]" zurückgibt.
  • SmsNotifier.php: Erstelle ein Trait namens SmsNotifier mit einer Methode notify(string $message), die "SMS: [message]" zurückgibt.
  • AlertService.php: Erstelle eine Klasse AlertService, die beide Traits verwendet. Da beide Traits über eine Methode notify() verfügen, musst du diesen Konflikt lösen:
    • Verwende EmailNotifier::notify als standardmäßige notify()-Methode
    • Erstelle für die Methode SmsNotifier::notify ein Alias notifyBySms
    Füge außerdem eine Methode notifyAll(string $message) hinzu, die beide Benachrichtigungsmethoden aufruft und ihre Ergebnisse in separaten Zeilen kombiniert zurückgibt.
  • main.php: Binde alle erforderlichen Dateien ein und erstelle eine Instanz von AlertService. 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

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
?>
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