Menu
Coddy logo textTech

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 - V6

Klasa 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.

challenge icon

Wyzwanie

Łatwy

Stwó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 $brand przechowującą nazwę producenta
    • Właściwość protected $modelNumber przechowującą wewnętrzny identyfikator
    • Właściwość private $manufacturingCode przechowującą dane dostępne wyłącznie dla fabryki
    Konstruktor powinien przyjmować wszystkie trzy wartości. Dodaj metodę private getManufacturingCode(), która zwraca kod produkcyjny. Dodaj metodę public getModelInfo(), która zwraca "Model: [modelNumber]". Na koniec dodaj metodę public getFullCode(), która zwraca "[brand]-[manufacturingCode]". Pokazuje to, jak sama klasa może uzyskiwać dostęp do swoich prywatnych składowych.
  • Smartphone.php: Utwórz klasę Smartphone, która dziedziczy po Device. 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 $brand oraz 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 publicznej getFullCode().
  • main.php: Dołącz plik Smartphone. Otrzymasz cztery dane wejściowe: nazwę marki, numer modelu, kod produkcyjny i system operacyjny. Utwórz instancję Smartphone z tymi wartościami. Wypisz trzy wiersze:
    • Wynik wywołania getDeviceDetails()
    • Wynik wywołania odziedziczonej metody getModelInfo()
    • Wynik wywołania odziedziczonej metody getFullCode()

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()
?>
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator PHP online