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 операторы бар.
Осы оператордың көмегімен Trait2 трейтінің
сол сияқты әдісінің орнына Trait1 трейтінің
method әдісін қолданамыз:
<?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;
?>
Trait1, Trait2 және Trait3
атаулары бар 3 трейт жасаңыз. Бірінші
трейтте 1 қайтаратын method әдісі,
екінші трейтте - бірдей атты әдіс, 2 қайтаратын,
ал үшінші трейтте - бірдей атты әдіс,
3 қайтаратын болсын.
Біздің жасаған үш трейтімізді де қолданатын
Test класын жасаңыз. Осы класта
қосылған трейттер әдістерінің нәтижелерінің
қосындысын қайтаратын getSum әдісін жасаңыз.