Approfondimento sui modificatori di accesso
Fa parte della sezione Programmazione orientata agli oggetti del percorso PHP di Coddy. Lezione 39 di 91.
Ora che hai compreso i tre modificatori di accesso, esploriamo come si comportano negli scenari di ereditarietà. L'intuizione fondamentale è che i membri protected diventano accessibili alle classi figlie, mentre i membri private rimangono nascosti anche ai figli.
<?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 would cause an error - private!
// $this->getSerial() would also fail - private method!
}
}
$car = new Car("Toyota", "V6", "ABC123");
echo $car->getDetails();
Output:
Toyota - V6La classe Car può accedere a $brand (pubblico) e chiamare getEngineInfo() (protetto), ma non può accedere a $serialNumber o getSerial() perché sono privati di Vehicle. Questa distinzione ti permette di condividere alcuni dettagli interni con le classi figlie, mantenendone altri completamente nascosti.
Punto chiave: Usa protected quando le classi figlie devono accedere ai dati interni o ai metodi, e private quando nemmeno le classi figlie dovrebbero intervenire su determinati dettagli di implementazione.
Sfida
FacileCreiamo un sistema di gestione dei dispositivi che esplora il comportamento dei modificatori di accesso nell’ereditarietà. Creerai una classe base Device con proprietà a diversi livelli di visibilità, poi la estenderai con una classe Smartphone che mostra a quali membri le classi figlie possono o non possono accedere.
Organizzerai il codice in tre file:
Device.php: crea una classeDeviceche rappresenta dispositivi elettronici con diversi livelli di sensibilità dei dati. Includi:- Una proprietà
public$brandper il nome del produttore - Una proprietà
protected$modelNumberper l’identificazione interna - Una proprietà
private$manufacturingCodeper i dati riservati alla fabbrica
privategetManufacturingCode()che restituisce il codice di produzione. Aggiungi un metodopublicgetModelInfo()che restituisce"Model: [modelNumber]". Infine, aggiungi un metodopublicgetFullCode()che restituisce"[brand]-[manufacturingCode]". Questo dimostra come la classe stessa possa accedere ai propri membri privati.- Una proprietà
Smartphone.php: crea una classeSmartphoneche estendeDevice. Includi il file Device. Il costruttore deve accettare brand, modelNumber, manufacturingCode e il nome di un sistema operativo. Chiama il costruttore del genitore con i primi tre valori, poi memorizza il sistema operativo in una proprietà privata. Aggiungi un metodo pubblicogetDeviceDetails()che restituisce"[brand] [modelNumber] running [os]". Nota che puoi accedere direttamente alla proprietà pubblica$brande alla proprietà protetta$modelNumber, ma non puoi accedere direttamente alla proprietà privata$manufacturingCode: dovrai invece usare il metodo pubblico ereditatogetFullCode().main.php: includi il file Smartphone. Riceverai quattro input: un nome di marca, un numero di modello, un codice di produzione e un sistema operativo. Crea un’istanza diSmartphonecon questi valori. Stampa tre righe:- Il risultato della chiamata a
getDeviceDetails() - Il risultato della chiamata al metodo ereditato
getModelInfo() - Il risultato della chiamata al metodo ereditato
getFullCode()
- Il risultato della chiamata a
Questa sfida mette in evidenza la distinzione fondamentale: la classe Smartphone può usare liberamente la proprietà protetta $modelNumber ereditata da Device, ma la proprietà privata $manufacturingCode e il metodo getManufacturingCode() restano completamente nascosti: sono accessibili solo tramite l’interfaccia pubblica che Device sceglie di esporre.
Provalo tu
<?php
require_once 'Smartphone.php';
// Leggi i dati di input
$brand = trim(fgets(STDIN));
$modelNumber = trim(fgets(STDIN));
$manufacturingCode = trim(fgets(STDIN));
$os = trim(fgets(STDIN));
// TODO: Crea un'istanza di Smartphone con i valori di input
// TODO: Stampa il risultato di getDeviceDetails()
// TODO: Stampa il risultato del metodo ereditato getModelInfo()
// TODO: Stampa il risultato del metodo ereditato getFullCode()
?>Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti della programmazione orientata agli oggetti
File esterniIntroduzione alla programmazione orientata agli oggettiClassi e oggettiLa parola chiave $thisMetodiProprietàCostruttore (__construct)Distruttore (__destruct)Riepilogo - Calcolatrice semplice4Ereditarietà
Ereditarietà di baseLa parola chiave parent::Sovrascrittura dei metodiLa parola chiave finalClassi astratteRiepilogo - Gerarchia dei dipendenti7Incapsulamento
Pubblico, Protetto, PrivatoApprofondimento sui modificatori di accessoGetter e SetterOccultamento delle informazioniPromozione dei parametri del costruttore (8.0)Riepilogo - Sistema di gestione dei registri degli studenti10Concetti avanzati di programmazione a oggetti
Composizione vs ereditarietàDependency InjectionClassi anonimeEnumerazioni (PHP 8.1)Fibers (PHP 8.1)Approfondimento sulla clonazione degli oggettiGeneratori e iteratori13Modelli di progettazione, parte 2
Modello CommandModello AdapterModello DecoratorModello Template MethodModello StateModello CompositeModello Repository2Namespace e autoloading
Introduzione ai namespaceLa keyword useStandard di autoloading PSR-4Autoloader di ComposerRiepilogo - Progetto organizzato5Interfacce e contratti
Introduzione alle interfacceImplementare le interfacceImplementare più interfacceInterfaccia vs classe astrattaType hinting con le interfacceRiepilogo - Calcolatore di forme8Metodi magici
Introduzione ai metodi magici__toString e __debugInfo__get, __set, __isset, __unset__call e __callStatic__clone e clonazione degli oggetti__serialize e __unserializeRiepilogo - Collezione personalizzata11Sistema dei tipi e gestione degli errori
Dichiarazioni di tipoTipi nullableTipi unione e intersezioneClassi di eccezioneGerarchia di eccezioni personalizzataTry, Catch, FinallyRiepilogo - Validatore di moduli14Progetto: Gestione della biblioteca
Panoramica del progettoClassi Libro e Utente3Proprietà delle classi
Proprietà di istanza e staticheCostanti nelle classiMetodi e proprietà staticiProprietà private e protectedProprietà readonly (PHP 8.1)Riepilogo - Gestore di conti bancari6Polimorfismo
Ridefinizione dei metodi, ripresaPolimorfismo tramite interfacceSuggerimenti sui tipi e tipi UnionBinding statico tardivoRiepilogo - Processore di pagamenti9Tratti
Introduzione ai trattiUtilizzare più trattiRisoluzione dei conflitti tra trattiMetodi astratti nei trattiTratti vs ereditarietà12Design pattern - Parte 1
Introduzione ai design patternPattern SingletonPattern FactoryPattern ObserverPattern StrategyEsercitati da solo: Compilatore PHP online