Klasy abstrakcyjne
Część sekcji Programowanie obiektowe ścieżki PHP w Coddy. Lekcja 25 z 91.
Klasa abstrakcyjna to klasa, której nie można bezpośrednio instancjonować. Służy jako szablon dla innych klas i definiuje metody, które muszą implementować klasy potomne. Klasę abstrakcyjną tworzy się za pomocą słowa kluczowego abstract.
<?php
abstract class Shape {
protected $color;
public function __construct($color) {
$this->color = $color;
}
abstract public function calculateArea();
public function getColor() {
return $this->color;
}
}
class Rectangle extends Shape {
private $width;
private $height;
public function __construct($color, $width, $height) {
parent::__construct($color);
$this->width = $width;
$this->height = $height;
}
public function calculateArea() {
return $this->width * $this->height;
}
}
$rect = new Rectangle("blue", 5, 3);
echo $rect->calculateArea();
Wynik:
15Klasa Shape deklaruje metodę abstrakcyjną calculateArea() bez podania jej implementacji. Każda klasa rozszerzająca Shape musi zaimplementować tę metodę. Zauważ, że klasy abstrakcyjne mogą również zawierać zwykłe metody, takie jak getColor(), które klasy potomne dziedziczą bezpośrednio.
Metody abstrakcyjne definiują, co musi robić klasa potomna, ale nie jak. Dzięki temu wszystkie kształty mają metodę calculateArea(), a każdy z nich może obliczać swoje pole w inny sposób.
Najważniejsza kwestia: Klasy abstrakcyjne łączą strukturę dziedziczenia z wymuszonymi wymaganiami. Używaj ich, gdy chcesz współdzielić kod między powiązanymi klasami, jednocześnie upewniając się, że każda klasa potomna implementuje określone metody.
Wyzwanie
ŁatwyStwórzmy system odtwarzacza multimediów, który pokazuje, jak klasy abstrakcyjne definiują kontrakt, jednocześnie pozwalając różnym typom mediów na własną implementację odtwarzania.
Rozmieścisz kod w trzech plikach:
Media.php: Zdefiniuj abstrakcyjną klasęMedia, która będzie wzorcem dla wszystkich typów mediów. Powinna mieć chronioną właściwość$titleoraz konstruktor, który przyjmuje i ustawia tytuł. Dodaj metodę abstrakcyjną o nazwieplay(), którą muszą implementować klasy potomne. Dodaj też zwykłą metodęgetTitle(), która zwraca tytuł. Ta konkretna metoda zostanie odziedziczona przez wszystkie klasy potomne.Song.php: Zdefiniuj klasęSong, która rozszerzaMedia. Na początku pliku dołącz plik Media. Ta klasa dodaje właściwość$artist. Konstruktor powinien przyjmować tytuł i wykonawcę: użyjparent::__construct()dla tytułu, a następnie samodzielnie ustaw wykonawcę. Zaimplementuj wymaganą metodęplay(), aby zwracała"Playing song: [title] by [artist]".Podcast.php: Zdefiniuj klasęPodcast, która rozszerzaMedia. Na początku pliku dołącz plik Media. Ta klasa dodaje właściwość$episode(liczbę całkowitą). Konstruktor powinien przyjmować tytuł i numer odcinka: użyjparent::__construct()dla tytułu, a następnie ustaw odcinek. Zaimplementuj wymaganą metodęplay(), aby zwracała"Playing podcast: [title] - Episode [episode]".
W pliku main.php dołącz pliki Song i Podcast. Otrzymasz cztery dane wejściowe: tytuł utworu, nazwę wykonawcy, tytuł podcastu i numer odcinka (jako ciąg znaków do konwersji na liczbę całkowitą). Utwórz obiekty Song i Podcast z tymi wartościami. Wyświetl wynik wywołania play() najpierw dla utworu, a następnie dla podcastu, każdy w osobnym wierszu.
To wyzwanie pokazuje, jak klasy abstrakcyjne definiują kontrakt: każdy typ mediów musi mieć metodę play(), ale każdy typ implementuje ją inaczej. Abstrakcyjnej klasy Media nie można bezpośrednio instancjonować; służy ona wyłącznie do zapewnienia struktury i wspólnych funkcjonalności klasom potomnym.
Spróbuj swoich sił
<?php
require_once 'Song.php';
require_once 'Podcast.php';
// Wczytaj dane wejściowe
$songTitle = trim(fgets(STDIN));
$artistName = trim(fgets(STDIN));
$podcastTitle = trim(fgets(STDIN));
$episodeNumber = intval(trim(fgets(STDIN)));
// TODO: Utwórz obiekt Song, używając songTitle i artistName
// TODO: Utwórz obiekt Podcast, używając podcastTitle i episodeNumber
// TODO: Wypisz wynik wywołania play() na obiekcie Song
// TODO: Wypisz wynik wywołania play() na obiekcie Podcast
?>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