Modyfikatory dostępu w szczegółach
Część sekcji Programowanie obiektowe ścieżki PHP w Coddy. Lekcja 39 z 91.
Teraz, gdy rozumiesz już trzy modyfikatory dostępu, przyjrzyjmy się, jak zachowują się w przypadku dziedziczenia. Kluczowe jest to, że składowe protected stają się dostępne dla klas potomnych, podczas gdy składowe private pozostają ukryte nawet przed nimi.
<?php
class Vehicle {
public $brand;
protected $engineType;
private $serialNumber;
public function __construct($brand, $engine, $serial) {
$this->brand = $brand;
$this->engineType = $engine;
$this->serialNumber = $serial;
}
private function getSerial() {
return $this->serialNumber;
}
protected function getEngineInfo() {
return $this->engineType;
}
}
class Car extends Vehicle {
public function getDetails() {
return $this->brand . " - " . $this->getEngineInfo();
// $this->serialNumber spowodowałoby błąd — jest prywatne!
// $this->getSerial() również zakończyłoby się błędem — to metoda prywatna!
}
}
$car = new Car("Toyota", "V6", "ABC123");
echo $car->getDetails();
Wynik:
Toyota - V6Klasa Car ma dostęp do $brand (publicznego) i może wywołać getEngineInfo() (chronioną), ale nie ma dostępu do $serialNumber ani getSerial(), ponieważ są prywatne dla Vehicle. To rozróżnienie pozwala udostępniać niektóre szczegóły wewnętrzne klasom potomnym, a inne całkowicie ukrywać.
Najważniejsza kwestia: Używaj protected, gdy klasy potomne potrzebują dostępu do wewnętrznych danych lub metod, a private, gdy nawet klasy potomne nie powinny mieć dostępu do niektórych szczegółów implementacji.
Wyzwanie
ŁatwyStwórzmy system zarządzania urządzeniami, który pokazuje, jak modyfikatory dostępu zachowują się w przypadku dziedziczenia. Utworzysz bazową klasę Device z właściwościami o różnych poziomach widoczności, a następnie rozszerzysz ją o klasę Smartphone, która pokaże, do których składowych klasy potomne mają dostęp, a do których nie.
Umieścisz kod w trzech plikach:
Device.php: Utwórz klasęDevice, która reprezentuje urządzenia elektroniczne o różnym poziomie wrażliwości danych. Dodaj:- Właściwość
public$brandprzechowującą nazwę producenta - Właściwość
protected$modelNumberprzechowującą wewnętrzny identyfikator - Właściwość
private$manufacturingCodeprzechowującą dane dostępne wyłącznie dla fabryki
privategetManufacturingCode(), która zwraca kod produkcyjny. Dodaj metodępublicgetModelInfo(), która zwraca"Model: [modelNumber]". Na koniec dodaj metodępublicgetFullCode(), która zwraca"[brand]-[manufacturingCode]". Pokazuje to, jak sama klasa może uzyskiwać dostęp do swoich prywatnych składowych.- Właściwość
Smartphone.php: Utwórz klasęSmartphone, która dziedziczy poDevice. Dołącz plik Device. Konstruktor powinien przyjmować markę, numer modelu, kod produkcyjny i nazwę systemu operacyjnego. Wywołaj konstruktor klasy nadrzędnej z pierwszymi trzema wartościami, a następnie zapisz system operacyjny w prywatnej właściwości. Dodaj metodę publicznągetDeviceDetails(), która zwraca"[brand] [modelNumber] running [os]". Zauważ, że możesz bezpośrednio uzyskać dostęp do publicznej właściwości$brandoraz chronionej właściwości$modelNumber, ale nie możesz bezpośrednio uzyskać dostępu do prywatnej właściwości$manufacturingCode: zamiast tego musisz użyć odziedziczonej metody publicznejgetFullCode().main.php: Dołącz plik Smartphone. Otrzymasz cztery dane wejściowe: nazwę marki, numer modelu, kod produkcyjny i system operacyjny. Utwórz instancjęSmartphonez tymi wartościami. Wypisz trzy wiersze:- Wynik wywołania
getDeviceDetails() - Wynik wywołania odziedziczonej metody
getModelInfo() - Wynik wywołania odziedziczonej metody
getFullCode()
- Wynik wywołania
To wyzwanie pokazuje kluczową różnicę: klasa Smartphone może swobodnie korzystać z chronionej właściwości $modelNumber odziedziczonej po Device, ale prywatna właściwość $manufacturingCode i metoda getManufacturingCode() pozostają całkowicie ukryte: dostęp do nich jest możliwy wyłącznie za pośrednictwem publicznego interfejsu, który udostępnia klasa Device.
Spróbuj swoich sił
<?php
require_once 'Smartphone.php';
// Odczytaj dane wejściowe
$brand = trim(fgets(STDIN));
$modelNumber = trim(fgets(STDIN));
$manufacturingCode = trim(fgets(STDIN));
$os = trim(fgets(STDIN));
// TODO: Utwórz instancję Smartphone z wartościami wejściowymi
// TODO: Wypisz wynik getDeviceDetails()
// TODO: Wypisz wynik odziedziczonej metody getModelInfo()
// TODO: Wypisz wynik odziedziczonej metody getFullCode()
?>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