Menu

Klasa abstrakcyjna w PHP: metody abstrakcyjne i zastosowania

Klasę abstrakcyjną w PHP deklaruje się jako abstract class Name i nie da się utworzyć jej instancji: istnieje po to, by ją rozszerzać. Może zawierać właściwości, konstruktor i gotowe metody oraz metody abstract bez treści, które musi zaimplementować każda klasa potomna.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

Klasę abstrakcyjną w PHP deklaruje się przez abstract class Name i nie można jej utworzyć przez new. Jest bazą dla innych klas: może mieć właściwości, konstruktor i gotowe metody oraz metody abstract bez treści, które musi zaimplementować każda klasa potomna.

describe() jest napisane raz w Shape i wywołuje area(), które dostarcza każdy potomek. Klasa abstrakcyjna gwarantuje, że ta metoda istnieje, więc describe() może na niej polegać.

Klasy abstrakcyjnej nie utworzysz przez new

Klasa abstrakcyjna jest celowo niekompletna: Shape::area() nie ma treści, więc zwykły obiekt Shape nie miałby czego wykonać. PHP odmawia jego utworzenia i rzuca Error:

Metody abstrakcyjne: zasady

Metoda abstrakcyjna ma sygnaturę i średnik zamiast treści. Każdy potomek musi ją zaimplementować ze zgodną sygnaturą i taką samą lub szerszą widocznością: metoda abstract protected może stać się w potomku protected albo public, nigdy private. Klasa z choćby jedną metodą abstrakcyjną sama musi być zadeklarowana jako abstrakcyjna.

Potomek, który pominie metodę abstrakcyjną, zatrzymuje skrypt, zanim cokolwiek się wykona, chyba że sam też jest zadeklarowany jako abstrakcyjny i zostawia tę metodę swoim potomkom:

PHP Fatal error:  Class Square contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Shape::area) in /home/index.php on line 3

Wzorzec metody szablonowej

Najczęstszy powód napisania klasy abstrakcyjnej: stała sekwencja kroków, z których kilka się różni. Klasa bazowa posiada sekwencję w metodzie final, a potomkowie uzupełniają kroki. Tutaj ten sam raport działa jako zwykły tekst i jako tabela HTML:

Uruchom, a zakładka Page pokaże tabelę HTML nad wersją tekstową. open() i close() mają domyślną treść, więc nadpisuje je tylko HtmlReport; row() jest abstrakcyjna, bo nie ma sensownej wartości domyślnej. Oznaczenie render() jako final nie pozwala potomkowi zmienić kolejności kroków.

Klasa abstrakcyjna może implementować interfejs

Klasa abstrakcyjna może zadeklarować implements i zostawić część metod interfejsu swoim potomkom. To standardowy sposób łączenia interfejsu (typu) z klasą bazową (wspólnym kodem):

Kod używa interfejsu Cache jako typu, więc klasa, która nie może rozszerzać BaseCache (bo już rozszerza coś innego), nadal może implementować Cache bezpośrednio.

Kiedy używać klasy abstrakcyjnej, a kiedy nie

Sięgnij po klasę abstrakcyjną, gdy klasy w rodzinie współdzielą prawdziwy kod: właściwości, konstruktor, metody takie same dla wszystkich. Jeśli baza zawierałaby wyłącznie metody abstrakcyjne, to jest to przebrany interfejs, a interfejs jest lepszym wyborem, bo klasa może implementować wiele interfejsów, ale rozszerzać tylko jedną klasę. Jeśli chcesz tylko współdzielić kilka metod pomocniczych między niepowiązanymi klasami, użyj traitu, zamiast wciskać je pod jednego rodzica.

Szybki test przed napisaniem abstract class: czy każdy potomek naprawdę jest rodzajem bazy (Circle jest Shape)? Jeśli uczciwa odpowiedź brzmi „potrafi to robić”, a nie „jest jednym z nich”, napisz interfejs.

Najczęściej zadawane pytania

Czym jest klasa abstrakcyjna w PHP?

Klasą zadeklarowaną jako abstract class Name, której nie można utworzyć przez new. Jest bazą dla innych klas: może zawierać właściwości, konstruktor i zwykłe metody oraz deklarować metody abstract, które musi zaimplementować każda klasa potomna.

Czym jest metoda abstrakcyjna w PHP?

Metodą zadeklarowaną z abstract i bez treści: abstract protected function render(array $rows): string;. Klasa, która ją zawiera, sama musi być zadeklarowana jako abstract, a każda nieabstrakcyjna klasa potomna musi zdefiniować metodę o zgodnej sygnaturze.

Czy klasa abstrakcyjna może mieć konstruktor w PHP?

Tak. Nie możesz wywołać new na klasie abstrakcyjnej, ale jej konstruktor wykonuje się przy tworzeniu klasy potomnej, automatycznie (jeśli potomek nie ma konstruktora) albo przez parent::__construct(...).

Czy można utworzyć instancję klasy abstrakcyjnej w PHP?

Nie. new Shape() na klasie abstrakcyjnej rzuca Error: Cannot instantiate abstract class Shape. Zamiast tego utwórz obiekt konkretnej klasy potomnej, na przykład new Circle(2).

Kiedy używać klasy abstrakcyjnej w PHP?

Gdy kilka powiązanych klas współdzieli prawdziwy kod (właściwości, konstruktor, wspólne metody) i różni się kilkoma krokami. Umieść wspólny kod w klasie abstrakcyjnej, a różniące się kroki zadeklaruj jako abstrakcyjne. Jeśli nie ma wspólnego kodu i potrzebujesz tylko kontraktu, użyj interfejsu.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ