Przesłanianie metod
Część sekcji Programowanie obiektowe ścieżki PHP w Coddy. Lekcja 23 z 91.
Czasami odziedziczona metoda z klasy nadrzędnej nie do końca odpowiada potrzebom klasy potomnej. Nadpisywanie metod pozwala klasie potomnej udostępnić własną implementację metody, która już istnieje w klasie nadrzędnej.
Aby przesłonić metodę, po prostu zdefiniuj metodę w klasie potomnej o tej samej nazwie co metoda klasy nadrzędnej:
<?php
class Animal {
public $name;
public function __construct($name) {
$this->name = $name;
}
public function speak() {
return "$this->name makes a sound";
}
}
class Cat extends Animal {
public function speak() {
return "$this->name says meow";
}
}
$cat = new Cat("Whiskers");
echo $cat->speak();
Wynik:
Whiskers says meowKlasa Cat całkowicie zastępuje metodę speak() klasy nadrzędnej własną wersją. Gdy wywołujesz speak() na obiekcie kota, PHP używa implementacji klasy potomnej.
Możesz również rozszerzyć działanie klasy nadrzędnej, łącząc parent:: z własną logiką:
<?php
class Dog extends Animal {
public function speak() {
return parent::speak() . " - woof woof!";
}
}
$dog = new Dog("Rex");
echo $dog->speak();
Wynik:
Rex makes a sound - woof woof!Kluczowa kwestia: Nadpisywanie metod pozwala klasom potomnym dostosować odziedziczone zachowanie. Możesz całkowicie zastąpić metodę lub użyć parent::, aby rozbudować pierwotną implementację.
Wyzwanie
ŁatwyStwórzmy system powiadomień, który pokazuje, jak klasy potomne mogą całkowicie zastępować lub rozszerzać metody klas nadrzędnych poprzez nadpisywanie metod.
Utworzysz trzy współpracujące ze sobą pliki, które będą wysyłać różne rodzaje powiadomień, każde z własnym zachowaniem:
Notification.php: Zdefiniuj klasęNotification, która będzie klasą bazową dla wszystkich typów powiadomień. Powinna mieć publiczną właściwość$recipientoraz konstruktor, który przyjmuje i ustawia odbiorcę. Dodaj metodęsend($message), która zwraca"Sending to [recipient]: [message]".UrgentNotification.php: Zdefiniuj klasęUrgentNotification, która rozszerzaNotification. Na początku dołącz plik Notification. Ta klasa powinna całkowicie nadpisywać metodęsend($message), aby zwracała"URGENT to [recipient]: [message]!!!": zwróć uwagę na prefiks "URGENT" i wykrzykniki na końcu. To pokazuje całkowite zastąpienie zachowania klasy nadrzędnej.LoggedNotification.php: Zdefiniuj klasęLoggedNotification, która rozszerzaNotification. Na początku dołącz plik Notification. Ta klasa powinna nadpisywać metodęsend($message), ale bazować na implementacji klasy nadrzędnej: wywołajparent::send($message)i dołącz" [logged]"do wyniku. To pokazuje rozszerzanie zachowania zamiast jego zastępowania.
W pliku main.php dołącz wszystkie trzy pliki z klasami powiadomień. Otrzymasz dwa dane wejściowe: imię odbiorcy i wiadomość do wysłania. Utwórz jedną instancję każdego typu powiadomienia (wszystkie z tym samym odbiorcą), a następnie wywołaj send() z wiadomością dla każdej z nich. Wypisz każdy wynik w osobnym wierszu, w tej kolejności: zwykłe powiadomienie, pilne powiadomienie, a następnie powiadomienie z logowaniem.
To wyzwanie pokazuje dwa podejścia do nadpisywania metod: UrgentNotification całkowicie zastępuje logikę klasy nadrzędnej własnym formatowaniem, podczas gdy LoggedNotification używa parent::, aby zachować oryginalne zachowanie i je rozszerzyć.
Spróbuj swoich sił
<?php
require_once 'Notification.php';
require_once 'UrgentNotification.php';
require_once 'LoggedNotification.php';
// Wczytaj dane wejściowe
$recipient = trim(fgets(STDIN));
$message = trim(fgets(STDIN));
// TODO: Utwórz po jednej instancji każdego typu powiadomienia (wszystkie z tym samym odbiorcą)
// TODO: Wywołaj send() z wiadomością dla każdego powiadomienia
// Wypisz każdy wynik w osobnym wierszu w tej kolejności:
// 1. Zwykłe powiadomienie
// 2. Pilne powiadomienie
// 3. Powiadomienie z zapisem w dzienniku
?>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