A trait metódusok konfliktusainak feloldása az OOP-ban PHP-ben
Mivel egy osztály több traitet is használhat, előfordulhat egy olyan probléma, amikor két traitnek azonos nevű metódusa van.
Ebben az esetben a PHP halálos hibát jelez. A helyzet javításához explicit módon kell feloldani a névkonfliktust. Hogyan történik ez - nézzük meg a gyakorlatban.
Tegyük fel, hogy van két traitünk azonos
method metódussal:
<?php
trait Trait1
{
private function method()
{
return 1;
}
}
trait Trait2
{
private function method()
{
return 2;
}
}
?>
Tegyük fel, hogy van egy Test osztályunk is,
amely mindkét traitünket használja. Ha egyszerűen
mindkét traitet csatoljuk az osztályunkhoz, akkor
a PHP hibát jelez, mivel a trait-eknek vannak
egymást fedő metódusaik:
<?php
// Ez a kód hibát fog jelezni!
class Test
{
use Trait1, Trait2; // trait-ek csatolása
}
?>
Oldjuk fel a trait-jeink névkonfliktusát.
Ehhez létezik egy speciális operátor,
a insteadof. Ezzel az operátorral
a Trait1 trait method metódusát
fogjuk használni a Trait2 trait azonos
nevű metódusa helyett:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
}
new Test;
?>
Amint látod, a szintaxis a következő: először
a trait neve, majd kettőspont, majd a metódus neve,
majd a insteadof operátorunk
és a második trait neve.
Vizsgáljuk meg:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
public function __construct()
{
echo $this->method(); // 1-et ír ki, mert ez az első trait metódusa
}
}
new Test;
?>
Tehát az osztályunkban meghatároztuk, hogy ha
a method metódust használjuk, akkor
azt az első traitből kell venni. Megfordítható is
- vehetjük a második trait metódusát:
<?php
class Test
{
use Trait1, Trait2 {
Trait2::method insteadof Trait1;
}
public function __construct()
{
echo $this->method(); // 2-t ír ki, mert ez a második trait metódusa
}
}
new Test;
?>
Mindenesetre, ha azt határozzuk meg, hogy egy trait
metódusát használjuk, akkor a másik trait metódusa
elérhetetlenné válik. Használhatjuk a másik trait
metódusát is, átnevezve azt a
as kulcsszóval, így:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method() + $this->method2(); // 3-at fog kiírni
}
}
new Test;
?>
Szükség esetén átnevezhetjük az első trait metódusát is:
<?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(); // 3-at fog kiírni
}
}
new Test;
?>
A as kulcsszó használata
a fő metódus insteadof-val való
megadása nélkül nem megengedett, ez hibát jelezne:
<?php
// Ez az osztály hibát fog jelezni:
class Test
{
use Trait1, Trait2 {
Trait1::method as method1;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method1() + $this->method2();
}
}
new Test;
?>
Készíts 3 traitet Trait1,
Trait2 és Trait3 nevekkel. Legyen az első
traitben egy method metódus, amely
1-et ad vissza, a második traitben - egy azonos nevű
metódus, amely 2-t ad vissza, a harmadik
traitben pedig - egy azonos nevű metódus,
amely 3-at ad vissza.
Készíts egy Test osztályt, amely
mindhárom általunk létrehozott traitet használja. Készíts ebben az
osztályban egy getSum metódust, amely
visszaadja a csatolt trait-ek metódusainak eredményeinek összegét.