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 occurredOperator 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.
Wyzwanie
ŁatwyZbudujmy 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 nazwieEmailNotifierz metodąnotify(string $message), która zwraca"Email: [message]".SmsNotifier.php: Utwórz cechę o nazwieSmsNotifierz 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::notifyjako domyślnej metodynotify() - Utwórz alias
notifyBySmsdla metodySmsNotifier::notify
notifyAll(string $message), która wywołuje obie metody powiadomień i zwraca ich wyniki w osobnych wierszach.- Użyj
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ą
- Wynik wywołania
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
?>Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrzneWprowadzenie do programowania obiektowegoKlasy a obiektySłowo kluczowe $thisMetodyWłaściwościKonstruktor (__construct)Destruktor (__destruct)Powtórka — prosty kalkulator4Dziedziczenie
Podstawy dziedziczeniaSłowo kluczowe parent::Przesłanianie metodSłowo kluczowe finalKlasy abstrakcyjnePowtórzenie – hierarchia pracowników7Enkapsulacja
Public, protected, privateModyfikatory dostępu w szczegółachGettery i setteryUkrywanie informacjiPromocja parametrów konstruktora (8.0)Podsumowanie — system ewidencji studentów2Przestrzenie nazw i autoloading
Wprowadzenie do przestrzeni nazwSłowo kluczowe useStandard autoloadingu PSR-4Autoloader ComposeraPodsumowanie – uporządkowany projekt5Interfejsy i kontrakty
Wprowadzenie do interfejsówImplementowanie interfejsówImplementowanie wielu interfejsówInterfejs a klasa abstrakcyjnaPodpowiadanie typów za pomocą interfejsówPodsumowanie — kalkulator kształtów8Metody magiczne
Wprowadzenie do metod magicznych__toString i __debugInfo__get, __set, __isset, __unset__call i __callStatic__clone i klonowanie obiektów__serialize i __unserializePodsumowanie — własna kolekcja11System typów i obsługa błędów
Deklaracje typówTypy nullableTypy sumy i przecięciaKlasy wyjątkówNiestandardowa hierarchia wyjątkówTry, Catch, FinallyPodsumowanie — walidator formularzy14Projekt: Zarządzanie biblioteką
Przegląd projektuKlasy książki i użytkownika3Właściwości klas
Właściwości instancji a właściwości statyczneStałe w klasachMetody i właściwości statyczneWłaściwości prywatne i chronioneWłaściwości tylko do odczytu (PHP 8.1)Podsumowanie — menedżer kont bankowych6Polimorfizm
Ponowne omówienie nadpisywania metodPolimorfizm za pomocą interfejsówPodpowiedzi typów i typy sumyPóźne wiązanie statycznePodsumowanie — procesor płatności9Cechy
Wprowadzenie do cechKorzystanie z wielu cechRozwiązywanie konfliktów cechMetody abstrakcyjne w cechachCechy a dziedziczenie12Wzorce projektowe, część 1
Wprowadzenie do wzorców projektowychWzorzec SingletonWzorzec FactoryWzorzec ObserverWzorzec StrategyPoćwicz samodzielnie: Kompilator PHP online