Wprowadzenie do cech
Część sekcji Programowanie obiektowe ścieżki PHP w Coddy. Lekcja 51 z 91.
PHP obsługuje tylko dziedziczenie pojedyncze — klasa może rozszerzać tylko jedną klasę nadrzędną. Ale co, jeśli chcesz współdzielić funkcjonalność między wieloma niepowiązanymi klasami? Właśnie tutaj przydają się cechy.
Cecha to mechanizm ponownego wykorzystania kodu, który pozwala definiować metody i właściwości możliwe do wstawienia do wielu klas. Pomyśl o cechach jak o kopiowaniu i wklejaniu na poziomie języka — kod z cechy staje się częścią klasy, która z niej korzysta.
<?php
trait Timestampable {
private string $createdAt;
public function setCreatedAt(): void {
$this->createdAt = date('Y-m-d H:i:s');
}
public function getCreatedAt(): string {
return $this->createdAt;
}
}
class Article {
use Timestampable;
public function __construct(public string $title) {
$this->setCreatedAt();
}
}
$article = new Article("PHP Traits");
echo $article->getCreatedAt();
Słowo kluczowe use wewnątrz klasy importuje składowe cechy. Teraz Article ma dostęp do setCreatedAt() i getCreatedAt(), tak jakby były zdefiniowane bezpośrednio w klasie.
Tę samą cechę można wykorzystać w zupełnie niezwiązanych ze sobą klasach — klasie Comment, klasie User lub dowolnej innej klasie, która potrzebuje funkcjonalności związanej ze znacznikami czasu. Rozwiązuje to ograniczenie pojedynczego dziedziczenia, umożliwiając poziome współdzielenie kodu w hierarchii klas.
Wyzwanie
ŁatwyZbudujmy prosty system powitań, który pokazuje, jak traity pozwalają współdzielić funkcjonalność między niepowiązanymi klasami. Utworzysz trait zapewniający możliwość witania, a następnie użyjesz go w dwóch zupełnie różnych klasach.
Rozmieścisz kod w trzech plikach:
Greetable.php: Utwórz trait o nazwieGreetable, który zapewnia funkcjonalność powitania. Trait powinien mieć:- Prywatną właściwość
$greeting(string) - Metodę
setGreeting(string $greeting), która zapisuje wiadomość powitalną - Metodę
greet(), która zwraca wiadomość powitalną
- Prywatną właściwość
Person.php: Utwórz klasęPerson, która używa traituGreetable. Dołącz plik traitu i użyj promocji konstruktora, aby zdefiniować publiczną właściwość$name. W konstruktorze wywołajsetGreeting(), aby ustawić powitanie na"Hello, I'm [name]".Robot.php: Utwórz klasęRobot, która również używa traituGreetable. Dołącz plik traitu i użyj promocji konstruktora, aby zdefiniować publiczną właściwość$model. W konstruktorze wywołajsetGreeting(), aby ustawić powitanie na"Beep boop, I am model [model]".
W pliku main.php dołącz oba pliki klas. Otrzymasz dwa dane wejściowe: imię osoby i numer modelu robota. Utwórz instancje obu klas i wyświetl ich powitania w osobnych wierszach.
To pokazuje siłę traitów: Person i Robot to zupełnie niepowiązane klasy, które nie mają wspólnej klasy nadrzędnej, a mimo to obie zyskują tę samą funkcjonalność powitania dzięki traitowi. Każda klasa dostosowuje sposób korzystania z tej funkcjonalności do własnych potrzeb.
Spróbuj swoich sił
<?php
require_once 'Person.php';
require_once 'Robot.php';
// Odczytaj dane wejściowe
$name = trim(fgets(STDIN));
$model = trim(fgets(STDIN));
// TODO: Utwórz instancję Person z podanym imieniem
// TODO: Utwórz instancję Robot z podanym modelem
// TODO: Wypisz powitanie Person
// TODO: Wypisz powitanie Robot (w nowym wierszu)
?>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