Cechy a dziedziczenie
Część sekcji Programowanie obiektowe ścieżki PHP w Coddy. Lekcja 55 z 91.
Skoro już rozumiesz, jak działają cechy, wyjaśnijmy, kiedy używać cech, a kiedy dziedziczenia. Oba rozwiązania umożliwiają ponowne wykorzystanie kodu, ale służą różnym celom i mają odmienne właściwości.
Dziedziczenie ustanawia relację „jest”. Klasa Dog rozszerzająca Animal oznacza, że pies jest zwierzęciem. Klasa potomna dziedziczy tożsamość klasy nadrzędnej i może być używana wszędzie tam, gdzie oczekiwany jest typ klasy nadrzędnej.
Cechy zapewniają możliwość „posiadania”. Gdy klasa używa cechy Loggable, ma funkcjonalność logowania — ale nie staje się loggerem. Cechy dodają zachowanie, nie zmieniając tego, czym klasa zasadniczo jest.
<?php
// Dziedziczenie: Dog JEST obiektem typu Animal
class Animal {
public function breathe(): void {
echo "Breathing";
}
}
class Dog extends Animal {
public function bark(): void {
echo "Woof!";
}
}
// Cecha: Dog MA możliwość logowania
trait Loggable {
public function log(string $msg): void {
echo "Log: $msg";
}
}
class Cat extends Animal {
use Loggable;
}
Najważniejsze różnice do zapamiętania:
| Aspekt | Dziedziczenie | Cechy |
|---|---|---|
| Relacja | jest-rodzajem | ma możliwości |
| Ograniczenie | Tylko jedna klasa nadrzędna | Dozwolonych jest wiele cech |
| Sprawdzanie typów | Działa z instanceof | Brak tożsamości typu |
| Najlepsze zastosowanie | Relacje hierarchiczne | Wspólne zachowania w niezwiązanych ze sobą klasach |
Używaj dziedziczenia, gdy klasy mają wspólną tożsamość. Używaj traitów, gdy niezwiązane ze sobą klasy potrzebują tej samej funkcjonalności, ale nie należą do tej samej hierarchii.
Wyzwanie
ŁatwyZbudujmy system pojazdów, który pokazuje, kiedy używać dziedziczenia, a kiedy traitów. Utworzysz hierarchię pojazdów o wspólnej tożsamości wynikającej z dziedziczenia, a jednocześnie dodasz przekrojowe możliwości za pomocą traitów.
Rozmieścisz kod w czterech plikach:
Trackable.php: Utwórz trait o nazwieTrackable, który zapewnia możliwość śledzenia GPS. Trait powinien zawierać:- Prywatną właściwość
$location(string) - Metodę
setLocation(string $location), która zapisuje bieżącą lokalizację - Metodę
getLocation(), która zwraca"Location: [location]"
- Prywatną właściwość
Vehicle.php: Utwórz bazową klasęVehicle, która ustanawia relację typu „jest”. Dołącz plik traitu. Użyj promocji konstruktora, aby zdefiniować chronioną właściwość$brand. Dodaj metodędescribe(), która zwraca"Vehicle: [brand]". Ta klasa powinna używać traituTrackable, ponieważ wszystkie pojazdy w naszej flocie będą wyposażone w GPS.Car.php: Utwórz klasęCar, która rozszerzaVehicle. Dołącz plik Vehicle. Użyj promocji konstruktora, aby przyjąć markę oraz prywatną właściwość$doors(liczba całkowita). Wywołaj konstruktor klasy nadrzędnej, przekazując markę. Nadpisz metodędescribe(), aby zwracała"Car: [brand] with [doors] doors".main.php: Dołącz plik Car. Otrzymasz trzy dane wejściowe: nazwę marki, liczbę drzwi i ciąg znaków określający lokalizację. Utwórz instancjęCar, ustaw jej lokalizację, a następnie wypisz dwa wiersze:- Wynik wywołania
describe() - Wynik wywołania
getLocation()
- Wynik wywołania
Zwróć uwagę, jak współdziałają tu dziedziczenie i traity: Car jest Vehicle (dziedziczenie ustanawia tożsamość), a Vehicle ma funkcję śledzenia (trait dodaje zachowanie). Możesz użyć instanceof Vehicle, aby sprawdzić, czy coś jest pojazdem, ale nie istnieje typ „Trackable”, względem którego można by to sprawdzić: to kluczowa różnica między tymi dwoma podejściami.
Spróbuj swoich sił
<?php
// Plik główny - utwórz i przetestuj instancję Car
// TODO: Dołącz plik Car.php
// Odczytaj dane wejściowe
$brand = trim(fgets(STDIN));
$doors = intval(trim(fgets(STDIN)));
$location = trim(fgets(STDIN));
// TODO: Utwórz instancję Car z wartościami brand i doors
// TODO: Ustaw lokalizację samochodu
// TODO: Wyświetl wynik describe()
// TODO: Wyświetl wynik getLocation()
?>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