⊗ppOpTrMC 79 of 107 menu

Вырашэнне канфліктаў метадаў трэйтаў у ААП у 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, які вяртае суму вынікаў метадаў падключаных трэйтаў.

azbydeenesfrkakkptruuz