Menu
Coddy logo textTech

Rozwiązywanie konfliktów cech

Część sekcji Programowanie obiektowe ścieżki PHP w Coddy. Lekcja 53 z 91.

Gdy dwie cechy definiują metody o tej samej nazwie, PHP zgłasza błąd krytyczny. Musisz jawnie wskazać PHP, jak rozwiązać ten konflikt, używając operatorów insteadof i as.

<?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");

Wynik:

File: Error occurred
DB: Error occurred

Operator insteadof wybiera metodę którego traitu użyć w przypadku konfliktu. W tym przykładzie wygrywa FileLogger::log i staje się domyślną metodą log(). Operator as tworzy alias, dzięki któremu możesz uzyskać dostęp do metody innego traitu pod inną nazwą.

Możesz także użyć as, aby zmienić widoczność metody:

<?php
trait Greeting {
    public function sayHello(): void {
        echo "Hello!";
    }
}

class Person {
    use Greeting {
        sayHello as private;
    }
}

To sprawia, że sayHello() jest prywatna w klasie Person, mimo że w traitcie jest publiczna. Rozwiązywanie konfliktów daje Ci precyzyjną kontrolę nad tym, jak metody traitu integrują się z Twoimi klasami.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system powiadomień, w którym różne kanały mogą wysyłać wiadomości, ale musimy rozwiązać konflikty, gdy wiele cech udostępnia metodę o tej samej nazwie.

Rozmieścisz kod w czterech plikach:

  • EmailNotifier.php: Utwórz cechę o nazwie EmailNotifier z metodą notify(string $message), która zwraca "Email: [message]".
  • SmsNotifier.php: Utwórz cechę o nazwie SmsNotifier z metodą notify(string $message), która zwraca "SMS: [message]".
  • AlertService.php: Utwórz klasę AlertService, która używa obu cech. Ponieważ obie cechy mają metodę notify(), musisz rozwiązać ten konflikt:
    • Użyj EmailNotifier::notify jako domyślnej metody notify()
    • Utwórz alias notifyBySms dla metody SmsNotifier::notify
    Dodaj też metodę notifyAll(string $message), która wywołuje obie metody powiadomień i zwraca ich wyniki w osobnych wierszach.
  • main.php: Dołącz wszystkie niezbędne pliki i utwórz instancję AlertService. Otrzymasz jedno wejście: ciąg znaków będący wiadomością. Wypisz trzy wiersze:
    • Wynik wywołania notify() z wiadomością
    • Wynik wywołania notifyBySms() z wiadomością
    • Wynik wywołania notifyAll() z wiadomością

To pokazuje, jak insteadof rozstrzyga, która metoda cechy zostanie użyta w przypadku konfliktu nazw, a as pozwala zachować dostęp do metody drugiej cechy pod inną nazwą.

Spróbuj swoich sił

<?php
require_once 'AlertService.php';

// Odczytaj dane wejściowe
$message = trim(fgets(STDIN));

// TODO: Utwórz instancję AlertService

// TODO: Wypisz wynik wywołania notify() z komunikatem

// TODO: Wypisz wynik wywołania notifyBySms() z komunikatem

// TODO: Wypisz wynik wywołania notifyAll() z komunikatem
?>
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator PHP online