Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 10 di 50
  • livello avanzato
Indice lezioni

Overriding e keyword final in PHP

Impariamo ad utilizzare l'overriding per sovrascrivere i metodi della classe padre in una classe figlia facendo in modo che le funzioni ridefinite abbiano precedenza su quelle della classe padre. Nello stesso tempo, scopriamo l'utilità della keyword final per impedire che i metodi all'interno della classe o l'intera classe sia estesa per ereditarietà o overriding.
Impariamo ad utilizzare l'overriding per sovrascrivere i metodi della classe padre in una classe figlia facendo in modo che le funzioni ridefinite abbiano precedenza su quelle della classe padre. Nello stesso tempo, scopriamo l'utilità della keyword final per impedire che i metodi all'interno della classe o l'intera classe sia estesa per ereditarietà o overriding.
Link copiato negli appunti

Come abbiamo appreso dalla precedente lezione, una classe (sottoclasse o classe figlia) può ereditare sia i metodi che le proprietà da un'altra classe (superclasse o classe padre). In questa lezione approfondiremo l'ereditarietà in PHP: come ereditare il costruttore/distruttore e la tecnica dell'overriding o ridefinizione.

Overriding

I metodi definiti in una classe padre, possono essere sovrascritti (overriding) in una classe figlia e, in questo caso, le funzioni ridefinite avranno precedenza su quelle della classe padre. Questo metodo è utile se si vuole utilizzare la funzionalità del genitore o semplicemente aggiungere ulteriori funzionalità nel metodo della sottoclasse. Per ridefinire un metodo della superclasse in una sottoclasse, si crea semplicemente un metodo nella classe figlia con lo stesso nome del metodo della classe padre.

<?php
// dichiarazione della classe Person
class Person {
	public $name;
	// costruttore
	function __construct($name) {
		echo "Chiamata costruttore della Superclasse"."<br>";
		// inizializzazione della proprietà $name
		$this->name = $name;
	}
	// metodi
	function viewHello() {
		echo "Hello ".$this->name."<br>";
	}
}
// definizione della sottoclasse Employees
class Employees extends Person {
	public $profile;
	// costruttore della sottoclasse
	function __construct($name, $profile) {
		parent::__construct($name); // chiamo il costruttore di Person
		$this->profile = $profile;  // inizializzo $profile
	}
	// metodi
	function viewHello() {
		parent::viewHello();
		echo "Profile: ".$this->profile."<br>";
	}
}
$customer = new Person("Giuseppe Rossi");
$customer->viewHello();
$employee = new Employees("Mario Rossi", "Admin");
$employee->viewHello();
?>

Come possiamo notare in questo caso, il metodo viewHello di Employees va a sovrascrivere quello di Person. Praticamente, il metodo viewHello di Employees ignora quello di Person.

Per utilizzare l'istanza $employee al fine di accedere al metodo viewHello di Person, utilizziamo la keyword parent, seguita dall'operatore di risoluzione di scope ("::") e dal nome dell'elemento desiderato. Questo permette di richiamare gli elementi della classe genitore direttamente nelle sottoclassi:

<?php
...
parent::metodo();
...
?>

Quindi, grazie all'uso della keyword parent, è possibile condividere informazioni tra le classi, senza la necessità di riscrivere un metodo, nel caso in cui questo venga ridefinito.

Ereditare il costruttore e il distruttore

In PHP, il costruttore e il distruttore possono essere ereditati nelle sottoclassi, così da evitare la riscrittura del codice. Infatti, di default, viene richiamato automaticamente quello della classe padre.

Invece, nell'esempio utilizzato precedentemente, la classe effettua un overriding del costruttore della classe base, per inizializzare la proprietà $profile. Per impostare anche l'attributo $name richiamiamo il costruttore della classe genitore tramite la parola chiave parent, che identifica appunto la classe padre Person.

<?php
...
// costruttore della sottoclasse
function __construct($name, $profile) {
	parent::__construct($name); // chiamo il costruttore di Person
	$this->profile = $profile;  // inizializzo $profile
}
...
?>

La keyword final

A volte, possono verificarsi situazioni in cui non si voglia attuare l'overriding o l'ereditarietà. Questo per evitare problemi di sicurezza, instabilità dell'applicazione, codice eccessivamente complesso e così via. In tali situazioni, è possibile impedire che i metodi all'interno della classe o addirittura l'intera classe sia estesa, utilizzando la parola chiave final prima della definizione del metodo e della classe.

Ad esempio:

<?php
class MyClass {
	//definizione metodo con keyword final
	final public function viewHello() {
		echo "Hello!";
	}
}
class MyClassSub extends MyClass {
	public function viewHello() {
		echo "Hello!";
	}
}
$myClass = new MyClass();
// stampa "Hello!"
$myClass->viewHello();
?>

<?php
//definizione classe con keyword final
final class MyClass {
	...
}
class MyClassSub extends MyClass {
	...
}
?>

Se proviamo ad estendere la classe MyClass e/o sovrascrivere il metodo viewHello() verranno generati i seguenti errori:

Fatal error: Cannot override final method MyClass::viewHello() in [...]

e

Fatal error: Class MyClassSub may not inherit from final class (MyClass) in [...]

Conclusioni

Con questa lezione dedicata all'overriding, alle tecniche per impedire la ridefinizione di metodi e l'estensione delle classi, si conclude il secondo ciclo della guida. Nei prossimi capitoli tratteremo due argomenti, la cui conoscenza è fondamentale nella programmazione orientata agli oggetti di PHP: le classi astratte e le interfacce.

Ti consigliamo anche