Słowo kluczowe final
Część sekcji Programowanie obiektowe ścieżki PHP w Coddy. Lekcja 24 z 91.
Chociaż dziedziczenie i nadpisywanie metod zapewniają elastyczność, czasami trzeba uniemożliwić zmianę określonych klas lub metod. Słowo kluczowe final zabezpiecza kod, gwarantując, że określone implementacje nie mogą zostać zmienione przez klasy potomne.
Gdy oznaczysz metodę jako final, żadna klasa potomna nie może jej przesłonić:
<?php
class BankAccount {
protected $balance;
public function __construct($balance) {
$this->balance = $balance;
}
final public function getAccountId() {
return "ACC-" . spl_object_id($this);
}
}
class SavingsAccount extends BankAccount {
public function addInterest() {
return $this->balance * 0.05;
}
}
$account = new SavingsAccount(1000);
echo $account->getAccountId();
Wynik:
ACC-1Metody getAccountId() nie można nadpisać w klasie SavingsAccount ani w żadnej innej klasie potomnej. Chroni to kluczową funkcjonalność, która musi pozostać spójna we wszystkich typach kont.
Możesz również oznaczyć całą klasę jako final, aby zapobiec dziedziczeniu:
<?php
final class SecurityManager {
public function authenticate($user) {
return "Authenticating $user";
}
}
$security = new SecurityManager();
echo $security->authenticate("admin");
Wynik:
Authenticating adminŻadna klasa nie może dziedziczyć po SecurityManager. Jest to przydatne w przypadku klas, w których bezpieczeństwo ma szczególne znaczenie, lub gdy projekt klasy jest ukończony i nie powinien być modyfikowany.
Najważniejsze: Użyj final w metodach, aby zapobiec ich przesłanianiu, jednocześnie umożliwiając dziedziczenie, lub w klasach, aby całkowicie uniemożliwić dziedziczenie. To narzędzie do ochrony krytycznego kodu, który musi działać dokładnie zgodnie z założeniami.
Wyzwanie
ŁatwyZbudujmy system zarządzania dokumentami, który pokazuje, jak słowo kluczowe final chroni kluczowe funkcje przed modyfikacją przez klasy potomne.
Utworzysz trzy współpracujące ze sobą pliki do zarządzania różnymi typami dokumentów, przy jednoczesnym zabezpieczeniu wybranych funkcji:
Document.php: Zdefiniuj klasęDocument, która będzie klasą bazową dla wszystkich dokumentów. Powinna mieć publiczną właściwość$titlei chronioną właściwość$author. Konstruktor przyjmuje tytuł i autora. Dodaj metodęfinalo nazwiegetSignature(), która zwraca"Signed by: [author]". Tej funkcji bezpieczeństwa nie mogą nigdy zmieniać klasy potomne. Dodaj także zwykłą metodęgetContent(), która zwraca"Document: [title]".Report.php: Zdefiniuj klasęReport, która rozszerza klasęDocument. Na początku dołącz plik Document. Ta klasa dodaje właściwość$department. Konstruktor powinien przyjmować tytuł, autora i dział: użyjparent::__construct()dla dwóch pierwszych argumentów, a następnie ustaw dział. Nadpisz metodęgetContent(), aby zwracała"Report: [title] ([department])". KlasaReportdziedziczy metodęgetSignature()oznaczoną jako final, której nie może zmienić.main.php: Dołącz plik Report. Otrzymasz trzy dane wejściowe: tytuł dokumentu, nazwisko autora i dział. Utwórz obiektReportz tymi wartościami. Wypisz wynik działania metodygetContent()w pierwszym wierszu, a następnie wynik działania metodygetSignature()w drugim wierszu.
To wyzwanie pokazuje, jak metody final chronią kluczowe funkcje: generowanie podpisu pozostaje spójne we wszystkich typach dokumentów, podczas gdy inne metody, takie jak getContent(), mogą być dostosowywane przez każdą klasę potomną. Klasa Report może zmienić sposób wyświetlania treści, ale format podpisu jest zablokowany w klasie nadrzędnej.
Spróbuj swoich sił
<?php
require_once 'Report.php';
// Odczytaj dane wejściowe
$title = trim(fgets(STDIN));
$author = trim(fgets(STDIN));
$department = trim(fgets(STDIN));
// TODO: Utwórz obiekt Report z wartościami wejściowymi
// TODO: Wypisz wynik getContent()
// TODO: Wypisz wynik getSignature()
?>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