Вырашэнне канфліктаў метадаў трэйтаў у ААП у PHP
Так як адзін клас можа выкарыстоўваць некалькі трэйтаў, то нас можа падпікаваць праблема, якая ўзнікае тады, калі два трэйты маюць аднайменныя метады.
У гэтым выпадку PHP выдасць фатальную памылку. Каб паправіць сітуацыю, трэба будзе вырашыць канфлікт імяў явным чынам. Як гэта робіцца - паглядзім на практыцы.
Хай у нас ёсць два трэйты з аднолькавым
метадам method:
<?php
trait Trait1
{
private function method()
{
return 1;
}
}
trait Trait2
{
private function method()
{
return 2;
}
}
?>
Хай у нас таксама ёсць клас Test,
які выкарыстоўвае абодва нашыя трэйты. Калі проста
падключыць абодва трэйты да нашага класа, то
PHP выдасць памылку, так як у трэйтаў ёсць
супадальныя метады:
<?php
// Гэты код выдасць памылку!
class Test
{
use Trait1, Trait2; // падключаем трэйты
}
?>
Давайце вырашым канфлікт імяў
нашых трэйтаў. Для гэтага існуе спецыяльны
аператар insteadof. З дапамогай гэтага аператара
будзем выкарыстоўваць метад method трэйта
Trait1 замест такога ж метаду трэйта
Trait2:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
}
new Test;
?>
Як вы бачыце, сінтаксіс тут наступны: спачатку
імя трэйта, потым два двукроп'і, потым імя
метаду, потым наш аператар insteadof
і імя другога трэйта.
Давайце праверым:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
public function __construct()
{
echo $this->method(); // вывядзе 1, бо гэта метад першага трэйта
}
}
new Test;
?>
Такім чынам, у нашым класе мы сказалі, што калі
выкарыстоўваецца метад method, то варта
браць яго з першага трэйта. Можна і наадварот
- узяць метад другога трэйта:
<?php
class Test
{
use Trait1, Trait2 {
Trait2::method insteadof Trait1;
}
public function __construct()
{
echo $this->method(); // вывядзе 2, бо гэта метад другога трэйта
}
}
new Test;
?>
У любым выпадку, калі мы паказваем выкарыстоўваць
метад аднаго трэйта, то метад другога трэйта
аказваецца недаступным. Можна выкарыстоўваць
і метад другога трэйта, перайменаваўшы яго
праз ключавое слова as, вось так:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method() + $this->method2(); // вывядзе 3
}
}
new Test;
?>
Пры жаданні можна перайменаваць і метад першага трэйта:
<?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
}
}
new Test;
?>
Выкарыстоўваць ключавое слова as без
вызначэння галоўнага метаду праз insteadof
нельга, гэта выдасць памылку:
<?php
// Гэты клас выдасць памылку:
class Test
{
use Trait1, Trait2 {
Trait1::method as method1;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method1() + $this->method2();
}
}
new Test;
?>
Зрабіце 3 трэйты з назвамі Trait1,
Trait2 і Trait3. Хай у першым
трэйце будзе метад method, які вяртае
1, у другім трэйце - аднайменны
метад, які вяртае 2, а ў трэцім
трэйце - аднайменны метад,
які вяртае 3.
Зрабіце клас Test, які выкарыстоўвае
ўсе тры створаныя намі трэйты. Зрабіце ў
гэтым класе метад getSum, які вяртае
суму вынікаў метадаў падключаных трэйтаў.