Rešavanje konflikata metoda trejtova u OOP u PHP-u
Pošto jedna klasa može da koristi više trejtova, može da se pojavi problem kada dva trejta imaju metode sa istim imenom.
U tom slučaju PHP će prijaviti fatalnu grešku. Da bi se situacija ispravila, potrebno je eksplicitno razrešiti konflikt imena. Kako se to radi - pogledaćemo u praksi.
Neka imamo dva trejta sa istim
metodom method:
<?php
trait Trait1
{
private function method()
{
return 1;
}
}
trait Trait2
{
private function method()
{
return 2;
}
}
?>
Neka takođe imamo klasu Test,
koja koristi oba naša trejta. Ako jednostavno
povežemo oba trejta sa našom klasom,
PHP će prijaviti grešku, jer trejtovi imaju
podudarajuće metode:
<?php
// Ovaj kod će prijaviti grešku!
class Test
{
use Trait1, Trait2; // povezujemo trejtove
}
?>
Hajde da razrešimo konflikt imena
naših trejtova. Za ovo postoji specijalni
operator insteadof. Pomoću ovog operatora
koristićemo metod method trejta
Trait1 umesto istog metoda trejta
Trait2:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
}
new Test;
?>
Kao što vidite, sintaksa je sledeća: prvo
ime trejta, onda dve tačke, onda ime
metoda, onda naš operator insteadof
i ime drugog trejta.
Hajde da proverimo:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
public function __construct()
{
echo $this->method(); // ispisaće 1, jer je to metod prvog trejta
}
}
new Test;
?>
Dakle, u našoj klasi smo rekli da ako
se koristi metod method, onda treba
da se uzme iz prvog trejta. Može i obrnuto
- uzeti metod drugog trejta:
<?php
class Test
{
use Trait1, Trait2 {
Trait2::method insteadof Trait1;
}
public function __construct()
{
echo $this->method(); // ispisaće 2, jer je to metod drugog trejta
}
}
new Test;
?>
U svakom slučaju, ako navedemo da se koristi
metod jednog trejta, onda metod drugog trejta
postaje nedostupan. Može se koristiti
i metod drugog trejta, preimenujući ga
preko ključne reči as, ovako:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method() + $this->method2(); // ispisaće 3
}
}
new Test;
?>
Po želji se može preimenovati i metod prvog trejta:
<?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(); // ispisaće 3
}
}
new Test;
?>
Korišćenje ključne reči as bez
definisanja glavnog metoda preko insteadof
je nemoguće, ovo će prijaviti grešku:
<?php
// Ova klasa će prijaviti grešku:
class Test
{
use Trait1, Trait2 {
Trait1::method as method1;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method1() + $this->method2();
}
}
new Test;
?>
Napravite 3 trejta sa nazivima Trait1,
Trait2 i Trait3. Neka u prvom
trejtu bude metod method, koji vraća
1, u drugom trejtu - metod sa istim imenom
koji vraća 2, a u trećem
trejtu - metod sa istim imenom
koji vraća 3.
Napravite klasu Test, koja koristi
sva tri napravljena trejta. Napravite u
toj klasi metod getSum, koji vraća
zbir rezultata metoda povezanih trejtova.