Řešení konfliktů metod traitů v OOP v PHP
Protože jedna třída může používat několik traitů, může nás potkat problém, který nastane, když dva traity mají metody se stejným názvem.
V tomto případě PHP vypíše fatální chybu. Abychom situaci napravili, bude nutné konflikt jmen explicitně vyřešit. Jak se to dělá - podíváme se v praxi.
Předpokládejme, že máme dva traity se stejnou
metodou method:
<?php
trait Trait1
{
private function method()
{
return 1;
}
}
trait Trait2
{
private function method()
{
return 2;
}
}
?>
Předpokládejme také, že máme třídu Test,
používající oba naše traity. Pokud jednoduše
připojíme oba traity k naší třídě,
PHP vypíše chybu, protože traity mají
shodné metody:
<?php
// Tento kód vypíše chybu!
class Test
{
use Trait1, Trait2; // připojujeme traity
}
?>
Pojďme vyřešit konflikt jmen
našich traitů. K tomu existuje speciální
operátor insteadof. Pomocí tohoto operátoru
budeme používat metodu method traitu
Trait1 namísto stejné metody traitu
Trait2:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
}
new Test;
?>
Jak vidíte, syntaxe je následující: nejprve
název traitu, pak dvě dvojtečky, pak název
metody, pak náš operátor insteadof
a název druhého traitu.
Pojďme to ověřit:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
public function __construct()
{
echo $this->method(); // vypíše 1, protože to je metoda prvního traitu
}
}
new Test;
?>
Takže v naší třídě jsme řekli, že pokud
se použije metoda method, měla by
se brát z prvního traitu. Lze to i naopak
- vzít metodu druhého traitu:
<?php
class Test
{
use Trait1, Trait2 {
Trait2::method insteadof Trait1;
}
public function __construct()
{
echo $this->method(); // vypíše 2, protože to je metoda druhého traitu
}
}
new Test;
?>
V každém případě, pokud určíme používat
metodu jednoho traitu, pak metoda druhého traitu
je nedostupná. Lze použít
i metodu druhého traitu, přejmenovat ji
pomocí klíč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 případě potřeby lze přejmenovat i metodu prvního traitu:
<?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žití klíčového slova as bez
určení hlavní metody pomocí insteadof
není možné, vypíše to chybu:
<?php
// Tato třída vypíše chybu:
class Test
{
use Trait1, Trait2 {
Trait1::method as method1;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method1() + $this->method2();
}
}
new Test;
?>
Vytvořte 3 traity s názvy Trait1,
Trait2 a Trait3. Nechť v prvním
traitu bude metoda method, vracející
1, v druhém traitu - stejnojmenná
metoda, vracející 2, a ve třetím
traitu - stejnojmenná metoda,
vracející 3.
Vytvořte třídu Test, používající
všechny tři vytvořené traity. Vytvořte v
této třídě metodu getSum, vracející
součet výsledků metod připojených traitů.