Risoluzione dei conflitti dei metodi dei trait nella OOP in PHP
Poiché una classe può utilizzare diversi trait, potremmo incontrare un problema che si verifica quando due trait hanno metodi con lo stesso nome.
In questo caso PHP genererà un errore fatale. Per risolvere la situazione, sarà necessario risolvere il conflitto dei nomi in modo esplicito. Vediamo come si fa nella pratica.
Supponiamo di avere due trait con lo stesso
metodo method:
<?php
trait Trait1
{
private function method()
{
return 1;
}
}
trait Trait2
{
private function method()
{
return 2;
}
}
?>
Supponiamo inoltre di avere una classe Test,
che utilizza entrambi i nostri trait. Se si
collegano semplicemente entrambi i trait alla nostra classe,
PHP genererà un errore, poiché i trait hanno
metodi in conflitto:
<?php
// Questo codice genererà un errore!
class Test
{
use Trait1, Trait2; // colleghiamo i trait
}
?>
Risolviamo il conflitto dei nomi
dei nostri trait. Per questo esiste un operatore
speciale insteadof. Con questo operatore
utilizzeremo il metodo method del trait
Trait1 invece dello stesso metodo del trait
Trait2:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
}
new Test;
?>
Come puoi vedere, la sintassi è la seguente: prima
il nome del trait, poi due due punti, poi il nome
del metodo, poi il nostro operatore insteadof
e il nome del secondo trait.
Verifichiamo:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
public function __construct()
{
echo $this->method(); // visualizzerà 1, poiché è il metodo del primo trait
}
}
new Test;
?>
Quindi, nella nostra classe abbiamo specificato che se
viene utilizzato il metodo method, si dovrebbe
prenderlo dal primo trait. Si può fare anche il contrario
- prendere il metodo del secondo trait:
<?php
class Test
{
use Trait1, Trait2 {
Trait2::method insteadof Trait1;
}
public function __construct()
{
echo $this->method(); // visualizzerà 2, poiché è il metodo del secondo trait
}
}
new Test;
?>
In ogni caso, se specifichiamo di utilizzare
il metodo di un trait, il metodo del secondo trait
risulta non accessibile. Si può utilizzare
anche il metodo del secondo trait, rinominandolo
tramite la parola chiave as, in questo modo:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method() + $this->method2(); // visualizzerà 3
}
}
new Test;
?>
Volendo, si può rinominare anche il metodo del primo trait:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
Trait1::method as method1;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method1() + $this->method2(); // visualizzerà 3
}
}
new Test;
?>
Non è possibile utilizzare la parola chiave as senza
definire il metodo principale tramite insteadof,
questo genererà un errore:
<?php
// Questa classe genererà un errore:
class Test
{
use Trait1, Trait2 {
Trait1::method as method1;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method1() + $this->method2();
}
}
new Test;
?>
Crea 3 trait con i nomi Trait1,
Trait2 e Trait3. Lascia che nel primo
trait ci sia un metodo method che restituisca
1, nel secondo trait - un metodo omonimo
che restituisca 2, e nel terzo
trait - un metodo omonimo
che restituisca 3.
Crea una classe Test che utilizzi
tutti e tre i trait da noi creati. Crea in
questa classe un metodo getSum che restituisca
la somma dei risultati dei metodi dei trait collegati.