Riešenie konfliktov metód traitov v OOP v PHP
Keďže jedna trieda môže použiť niekoľko traitov, môžeme naraziť na problém, ktorý nastáva v prípade, že dva traity majú metódy s rovnakým názvom.
V takom prípade PHP vyhodí fatálnu chybu. Aby sme situáciu napravili, budeme musieť konflikt mien vyriešiť explicitne. Ako sa to robí - uvidíme v praxi.
Predpokladajme, že máme dva traity s rovnakou
metódou method:
<?php
trait Trait1
{
private function method()
{
return 1;
}
}
trait Trait2
{
private function method()
{
return 2;
}
}
?>
Predpokladajme tiež, že máme triedu Test,
ktorá používa oba naše traity. Ak jednoducho
pripojíme oba traity k našej triede,
PHP vyhodí chybu, pretože traity majú
konfliktné metódy:
<?php
// Tento kód vyhodí chybu!
class Test
{
use Trait1, Trait2; // pripájame traity
}
?>
Poďme vyriešiť konflikt mien
našich traitov. Na to existuje špeciálny
operátor insteadof. Pomocou tohto operátora
budeme používať metódu method trait-u
Trait1 namiesto rovnakej metódy trait-u
Trait2:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
}
new Test;
?>
Ako vidíte, syntax je nasledovná: najprv
názov trait-u, potom dve dvojbodky, potom názov
metódy, potom náš operátor insteadof
a názov druhého trait-u.
Poďme to vyskúšať:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
public function __construct()
{
echo $this->method(); // vypíše 1, pretože to je metóda prvého trait-u
}
}
new Test;
?>
Takže, v našej triede sme povedali, že ak
sa používa metóda method, malo by sa
brať z prvého trait-u. Môžeme to urobiť aj naopak
- vziať metódu druhého trait-u:
<?php
class Test
{
use Trait1, Trait2 {
Trait2::method insteadof Trait1;
}
public function __construct()
{
echo $this->method(); // vypíše 2, pretože to je metóda druhého trait-u
}
}
new Test;
?>
V každom prípade, ak určíme použiť
metódu jedného trait-u, metóda druhého trait-u
sa stáva nedostupnou. Môžeme však použiť
aj metódu druhého trait-u, ak ju premenujeme
pomocou kľúčového slova as, takto:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method() + $this->method2(); // vypíše 3
}
}
new Test;
?>
V prípade potreby môžeme premenovať aj metódu prvého trait-u:
<?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(); // vypíše 3
}
}
new Test;
?>
Použitie kľúčového slova as bez
určenia hlavnej metódy pomocou insteadof
nie je možné, vyhodilo by to chybu:
<?php
// Táto trieda vyhodí chybu:
class Test
{
use Trait1, Trait2 {
Trait1::method as method1;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method1() + $this->method2();
}
}
new Test;
?>
Vytvorte 3 traity s názvami Trait1,
Trait2 a Trait3. Nech v prvom
traite bude metóda method, vracajúca
1, v druhom traite - metóda s rovnakým názvom,
vracajúca 2, a v treťom
traite - metóda s rovnakým názvom,
vracajúca 3.
Vytvorte triedu Test, používajúcu
všetky tri nami vytvorené traity. Vytvorte v
tejto triede metódu getSum, vracajúcu
súčet výsledkov metód pripojených traitov.