OOP PHP-s traitide meetodite konfliktide lahendamine
Kuna üks klass võib kasutada mitut trait'i, võib meid oodata probleem, mis tekib siis, kui kahel trait'il on samanimelised meetodid.
Sel juhul annab PHP välja fatal error. Olukorra parandamiseks tuleb nimede konflikt lahendada selgelt. Kuidas seda tehakse - vaatame praktikas.
Oletame, et meil on kaks trait'i sama
meetodiga method:
<?php
trait Trait1
{
private function method()
{
return 1;
}
}
trait Trait2
{
private function method()
{
return 2;
}
}
?>
Oletame, et meil on ka klass Test,
mis kasutab mõlemat meie trait'i. Kui lihtsalt
ühendada mõlemad trait'd meie klassiga, siis
annab PHP vea, kuna traitidel on
kattuvad meetodid:
<?php
// See kood annab vea!
class Test
{
use Trait1, Trait2; // ühendame trait'd
}
?>
Lahendame nüüd meie trait'ide nimede
konflikti. Selleks on olemas spetsiaalne
operaator insteadof. Selle operaatori abil
kasutame trait'i Trait1 meetodit
method sama nimega trait'i Trait2 meetodi asemel:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
}
new Test;
?>
Nagu näete, on süntaks siin järgmine: kõigepealt
trait'i nimi, siis koolonid, siis meetodi
nimi, siis meie operaator insteadof
ja teise trait'i nimi.
Kontrollime:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
public function __construct()
{
echo $this->method(); // väljastab 1, sest see on esimese trait'i meetod
}
}
new Test;
?>
Kokkuvõttes, meie klassis ütlesime, et kui
kasutatakse meetodit method, siis tuleks
võtta see esimesest trait'ist. Võib ka vastupidi
- võtta teise trait'i meetod:
<?php
class Test
{
use Trait1, Trait2 {
Trait2::method insteadof Trait1;
}
public function __construct()
{
echo $this->method(); // väljastab 2, sest see on teise trait'i meetod
}
}
new Test;
?>
Igal juhul, kui me määrame kasutama
ühe trait'i meetodit, siis teise trait'i meetod
jääb kättesaamatuks. Saab kasutada
ka teise trait'i meetodit, ümber nimetades selle
klausliga as, nagu nii:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method() + $this->method2(); // väljastab 3
}
}
new Test;
?>
Soovi korral saab ümber nimetada ka esimese trait'i meetodi:
<?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(); // väljastab 3
}
}
new Test;
?>
Klauslit as ei saa kasutada ilma
peamise meetodi määramiseta läbi insteadof,
see annaks vea:
<?php
// See klass annab vea:
class Test
{
use Trait1, Trait2 {
Trait1::method as method1;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method1() + $this->method2();
}
}
new Test;
?>
Tehke 3 trait'i nimetustega Trait1,
Trait2 ja Trait3. Olgu esimeses
trait'is meetod method, mis tagastab
1, teises trait'is - samanimeline
meetod, mis tagastab 2, ja kolmandas
trait'is - samanimeline meetod,
mis tagastab 3.
Tehke klass Test, mis kasutab
kõiki kolme meie poolt loodud trait'i. Tehke
selles klassis meetod getSum, mis tagastab
ühendatud trait'ide meetodite tulemuste summa.