Proseguendo il nostro viaggio per imparare php, vediamo, ora, uno dei vantaggi principali della programmazione orientata agli oggetti. Con la programmazione ad oggetti, infatti, abbiamo la possibilità di ridurre la duplicazione del codice (ovvero, la scrittura dello stesso codice più di una volta), grazie all’ aiuto dell’ereditarietà.
In ereditarietà abbiamo una classe, definita “genitore”, con i suoi metodi e le sue proprietà, e una o più classi “figlie”, che possono usufruire del codice della classe genitore.
Utilizzando l’ereditarietà, possiamo progettare un pezzo di codice riutilizzabile ogni qual volta servisse. PHP consente l’ereditarietà singola; in altri linguaggi di programmazione, tuttavia, è anche possibile utilizzare l’ereditarietà multipla, dove una classe può ereditare metodi e proprietà da più di una classi padre.
In php è utile pensare alla classe figlia come ad una specializzazione della classe genitore.
Creazione di una classe estesa in PHP
Pronto a seguire gli step per la creazione di una classe estesa in php? Bene!
Per rinfrescarci la memoria, andiamo a ribadire come si crea una classe.
class Person { //attributi public $name; public $surname; public $age; public function __construct($name, $surname, $age) { $this->name = $name; $this->surname = $surname; $this->age = $age; } } $persona1 = new Person("Mario" , "Rossi" , 26);
Ha funzionato? Perfetto! Proviamo, ora, a creare la prima classe che estende la classe Persona:
class Teacher extends Person { public $salary; public $subjects = []; public function __construct($name , $surname, $age, $subjects, $salary){ parent::__construct($name, $surname, $age); $this->salary = $salary; $this->subjects = $subjects; } }
Utilizzando la parola chiave extends , stiamo dichiarando che una classe eredita proprietà e metodi da un’altra classe. Possiamo dire che teacher è una specializzazione di person, infatti ha tutte le caratteristiche di person ma a queste ne aggiunge altre. Vediamo il caso in generale:
class Person { //Codice della classe padre } class Teacher extends Person { //Codice della classe figlia }
A questo punto andiamo a creare un’ altra classe figlia, diversa da Docente, ma sempre collegata alla classe padre Persona.
class Student extends Person { public $average; public $subjects = []; public function __construct($name , $surname, $age, $subjects, $average){ parent::__construct($name, $surname, $age); $this->average = $average; $this->subjects = $subjects; } }
Le classi figlie possono, così, utilizzare gli attributi ereditati dalla classe padre. Questo è possibile perché nella funzione costruttore della classe figlia, richiamiamo la funzione costruttore della classe padre, passando i parametri che verranno assegnati agli attributi ereditati.
Ricordi quando, nella guida precedente, abbiamo parlato degli access modifiers o indicatori di accessibilità? È giunta l’ora di approfondire.
Se sei stato attento, avrai certamente notato che, fino ad ora, nei nostri esempi, abbiamo impostato gli attributi dichiarati sempre con la keyword “public”. Perché l’abbiamo fatto? La keyword prima del nome dell’attributo indica la visibilità dell’attributo stesso. Per essere più precisi, il punto del programma dove può essere richiamato l’attributo.
Oltre a public, che abbiamo utilizzato finora, ci sono altri due tipi di visibilità: protected e private.
Gli attributi dichiarati public sono visibili e accessibili in tutte le parti del programma, mentre gli attributi dichiarati con protected e private sono visibili solo all’interno della classe stessa.
Vediamo un piccolo esempio:
class Person { public $name; protected $surname; public function __construct($name, $surname) { $this->name = $name; $this->surname = $surname; } } $persona1 = new Person("Mario", "Rossi"); var_dump($persona->name); //Mario var_dump($persona1->surname); //Cannot access protected property Person::$surname
Come possiamo vedere, il var_dump() di name restituisce il valore, mentre quello di surname restituisce un errore perchè è una proprietà protected e non vi si può accedere dall’esterno.
Per potervi accedere, abbiamo bisogno di un metodo che acceda alla proprietà dall’interno della classe.
public function tellMeYourSurname(){ echo "My surname is $this->surname"; } $persona1->tellMeYourSurname(); //My surname is Rossi
Visto che siamo riusciti ad accedere in lettura, possiamo riuscire ad accedervi anche in scrittura, quindi possiamo modificarlo utilizzando un metodo.
$persona1 = new Person("Mario", "Rossi"); //Public $persona1->name = "Giorgio"; var_dump($persona1->name);//Giorgio //Protected public function changeSurname(){ $this->surname = "Verdi"; } $persona1->changeSurname(); $persona1->tellMeYourSurname(); //My surname is Verdi
Gli attributi private, invece, vengono ereditati dalle sottoclassi, ma rimangono, comunque, visibili nella classe in cui sono dichiarati.