Ponowne omówienie nadpisywania metod
Część sekcji Programowanie obiektowe ścieżki PHP w Coddy. Lekcja 33 z 91.
W rozdziale „Dziedziczenie” poznaliście już nadpisywanie metod. Teraz zobaczmy, jak wiąże się ono z polimorfizmem — jednym z najpotężniejszych pojęć w programowaniu obiektowym.
Polimorfizm oznacza „wiele form”. Gdy nadpisujesz metodę w klasie potomnej, nadajesz jej inną formę, zachowując tę samą nazwę. Magia dzieje się wtedy, gdy pracujesz z obiektami za pośrednictwem ich typu nadrzędnego:
<?php
class Animal {
public function speak() {
return "Some sound";
}
}
class Dog extends Animal {
public function speak() {
return "Woof!";
}
}
class Cat extends Animal {
public function speak() {
return "Meow!";
}
}
function makeAnimalSpeak(Animal $animal) {
return $animal->speak();
}
echo makeAnimalSpeak(new Dog()) . "\n";
echo makeAnimalSpeak(new Cat());
Wynik:
Woof!
Meow!Funkcja makeAnimalSpeak() akceptuje dowolne zwierzę Animal. Nie wie ani nie obchodzi jej, czy otrzymuje obiekt Dog, czy Cat. PHP automatycznie wywołuje właściwą przesłoniętą metodę na podstawie rzeczywistego typu obiektu w czasie wykonywania.
To polimorfizm w działaniu.
To podejście pozwala pisać elastyczny kod, który działa z rodziną powiązanych obiektów bez znajomości ich konkretnych typów. Możesz później dodawać nowe klasy zwierząt, a funkcja będzie z nimi działać automatycznie.
Kluczowa kwestia: Nadpisywanie metod umożliwia polimorfizm, pozwalając różnym klasom różnie reagować na to samo wywołanie metody. Sposób reakcji jest określany w czasie wykonywania programu na podstawie rzeczywistego typu obiektu.
Wyzwanie
ŁatwyZbudujmy system instrumentów muzycznych, który demonstruje polimorfizm poprzez nadpisywanie metod. Utworzysz bazową klasę Instrument oraz dwie klasy potomne, z których każda będzie wydawać własny, niepowtarzalny dźwięk. Następnie użyjesz jednej funkcji, aby polimorficznie odtwarzać dowolny instrument.
Rozmieścisz swój kod w czterech plikach:
Instrument.php: Utwórz klasęInstrumentz chronioną właściwością$name, której wartość jest ustawiana przez konstruktor. Dodaj metodęplay(), która zwraca"[name] makes a sound". Stanowi to bazowe zachowanie, które klasy potomne będą nadpisywać.Guitar.php: Utwórz klasęGuitar, która dziedziczy poInstrument. Dołącz plik klasy nadrzędnej. Konstruktor przyjmuje nazwę i przekazuje ją do konstruktora klasy nadrzędnej. Nadpisz metodęplay(), aby zwracała"[name] strums a chord".Drum.php: Utwórz klasęDrum, która dziedziczy poInstrument. Dołącz plik klasy nadrzędnej. Konstruktor przyjmuje nazwę i przekazuje ją do konstruktora klasy nadrzędnej. Nadpisz metodęplay(), aby zwracała"[name] beats a rhythm".main.php: Dołącz pliki Guitar i Drum. Utwórz funkcję o nazwieperformWith, która przyjmuje parametr typuInstrument(z określonym typem) i zwraca wynik wywołania na nim metodyplay(). Ta funkcja demonstruje polimorfizm. Dzięki wskazówce typu klasy nadrzędnej działa z dowolnym typem instrumentu.
Otrzymasz dwa dane wejściowe: nazwę gitary i nazwę bębna. Utwórz obiekt Guitar i obiekt Drum z tymi nazwami. Przekaż każdy z nich do funkcji performWith() i wypisz wyniki: najpierw gitarę, potem bęben, każdy w osobnym wierszu.
Zwróć uwagę, że performWith() przyjmuje dowolny obiekt Instrument, a mimo to PHP automatycznie wywołuje właściwą, nadpisaną metodę play() na podstawie rzeczywistego typu obiektu w czasie działania programu. Tak właśnie działa polimorfizm!
Spróbuj swoich sił
<?php
// Dołącz pliki instrumentów
require_once 'Guitar.php';
require_once 'Drum.php';
// Odczytaj dane wejściowe
$guitarName = trim(fgets(STDIN));
$drumName = trim(fgets(STDIN));
// TODO: Utwórz funkcję o nazwie performWith, która:
// - Przyjmuje parametr typu Instrument (użyj deklaracji typu: Instrument $instrument)
// - Zwraca wynik wywołania play() na instrumencie
// TODO: Utwórz obiekt Guitar z $guitarName i obiekt Drum z $drumName
// TODO: Przekaż każdy z nich do performWith() i wypisz wyniki (najpierw gitara, potem bęben)
?>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