Treitų metodų konfliktų sprendimas OOP PHP
Kadangi viena klasė gali naudoti kelis treitus, mus gali ištikti problema, kuri kyla tada, kai du treitai turi vienodus metodus.
Tokiu atveju PHP išmes mirtinę klaidą. Norint išspręsti situaciją, reikės aiškiai išspręsti pavadinimų konfliktą. Kaip tai daroma - pažiūrėsime praktiškai.
Tarkime, kad turime du treitus su vienodais
metodais method:
<?php
trait Trait1
{
private function method()
{
return 1;
}
}
trait Trait2
{
private function method()
{
return 2;
}
}
?>
Tarkime, kad taip pat turime klasę Test,
kuri naudoja abu mūsų treitus. Jei tiesiog
prijungsime abu treitus prie mūsų klasės, tai
PHP išmes klaidą, nes treitai turi
sutampančius metodus:
<?php
// Šis kodas išmes klaidą!
class Test
{
use Trait1, Trait2; // prijungiame treitus
}
?>
Išspręskime mūsų treitų pavadinimų konfliktą.
Tam yra specialus operatorius insteadof. Naudodami šį operatorių
panaudosime treito Trait1 metodą
method vietoj to paties treito
Trait2 metodo:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
}
new Test;
?>
Kaip matote, sintaksė čia tokia: pirmiausia
treito pavadinimas, po to dvi dvitaškiai, po to metodo
pavadinimas, po to mūsų operatorius insteadof
ir antrojo treito pavadinimas.
Patikrinkime:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
public function __construct()
{
echo $this->method(); // išves 1, nes tai pirmojo treito metodas
}
}
new Test;
?>
Taigi, savo klasėje mes nurodėme, kad jei
naudojamas metodas method, tai reikia
imti jį iš pirmojo treito. Galima ir atvirkščiai
- paimti antrojo treito metodą:
<?php
class Test
{
use Trait1, Trait2 {
Trait2::method insteadof Trait1;
}
public function __construct()
{
echo $this->method(); // išves 2, nes tai antrojo treito metodas
}
}
new Test;
?>
Bet kuriuo atveju, jei nurodome naudoti
vieno treito metodą, tai antrojo treito metodas
tampa nepasiekiamas. Galima naudoti
ir antrojo treito metodą, pervadinus jį
naudojant raktinį žodį as, štai taip:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method() + $this->method2(); // išves 3
}
}
new Test;
?>
Jei norima, galima pervadinti ir pirmojo treito metodą:
<?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(); // išves 3
}
}
new Test;
?>
Naudoti raktinį žodį as be
pagrindinio metodo apibrėžimo naudojant insteadof
negalima, tai išmes klaidą:
<?php
// Ši klasė išmes klaidą:
class Test
{
use Trait1, Trait2 {
Trait1::method as method1;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method1() + $this->method2();
}
}
new Test;
?>
Sukurkite 3 treitus su pavadinimais Trait1,
Trait2 ir Trait3. Tegul pirmajame
treite būna metodas method, grąžinantis
1, antrajame treite - to paties pavadinimo
metodas, grąžinantis 2, o trečiajame
treite - to paties pavadinimo metodas,
grąžinantis 3.
Sukurkite klasę Test, naudojančią
visus tris mūsų sukurtus treitus. Sukurkite šioje
klasėje metodą getSum, grąžinantį
prijungtų treitų metodų rezultatų sumą.