Oplossen van method conflict in traits in OOP in PHP
Aangezien één klasse meerdere traits kan gebruiken, kunnen we een probleem tegenkomen dat zich voordoet wanneer twee traits methoden met dezelfde naam hebben.
In dit geval geeft PHP een fatale fout. Om de situatie te corrigeren, moet het conflict in namen expliciet worden opgelost. Hoe dit wordt gedaan - laten we in de praktijk bekijken.
Stel dat we twee traits hebben met dezelfde
methode method:
<?php
trait Trait1
{
private function method()
{
return 1;
}
}
trait Trait2
{
private function method()
{
return 2;
}
}
?>
Stel dat we ook een klasse Test hebben,
die beide onze traits gebruikt. Als we simpelweg
beide traits in onze klasse opnemen, dan
geeft PHP een fout, omdat de traits
strijdige methoden hebben:
<?php
// Deze code geeft een fout!
class Test
{
use Trait1, Trait2; // nemen traits op
}
?>
Laten we het naamconflict van onze traits oplossen.
Hiervoor bestaat een speciale operator insteadof.
Met deze operator gebruiken we de methode method van trait
Trait1 in plaats van dezelfde methode van trait
Trait2:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
}
new Test;
?>
Zoals je ziet, is de syntaxis als volgt: eerst
de naam van de trait, dan twee dubbele punten, dan de naam
van de methode, dan onze operator insteadof
en de naam van de tweede trait.
Laten we testen:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
public function __construct()
{
echo $this->method(); // geeft 1 weer, want dit is de methode van de eerste trait
}
}
new Test;
?>
Dus, in onze klasse hebben we gezegd dat als
methode method wordt gebruikt, deze
uit de eerste trait moet worden genomen. Het omgekeerde kan ook
- de methode van de tweede trait nemen:
<?php
class Test
{
use Trait1, Trait2 {
Trait2::method insteadof Trait1;
}
public function __construct()
{
echo $this->method(); // geeft 2 weer, want dit is de methode van de tweede trait
}
}
new Test;
?>
In ieder geval, als we specificeren dat we de methode
van de ene trait gebruiken, dan is de methode van de tweede trait
niet beschikbaar. We kunnen ook de methode van de tweede trait gebruiken
door deze een andere naam te geven via het sleutelwoord as, zoals hier:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method() + $this->method2(); // geeft 3 weer
}
}
new Test;
?>
Indien gewenst kan ook de methode van de eerste trait een andere naam krijgen:
<?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(); // geeft 3 weer
}
}
new Test;
?>
Het sleutelwoord as gebruiken zonder
het definiëren van een hoofdmetode via insteadof
is niet toegestaan, dit geeft een fout:
<?php
// Deze klasse geeft een fout:
class Test
{
use Trait1, Trait2 {
Trait1::method as method1;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method1() + $this->method2();
}
}
new Test;
?>
Maak 3 traits met de namen Trait1,
Trait2 en Trait3. Laat in de eerste
trait een methode method zitten, die
1 teruggeeft, in de tweede trait - een methode met dezelfde naam,
die 2 teruggeeft, en in de derde
trait - een methode met dezelfde naam,
die 3 teruggeeft.
Maak een klasse Test, die
alle drie de door ons gemaakte traits gebruikt. Maak in
deze klasse een methode getSum, die de
som van de resultaten van de methoden van de aangesloten traits teruggeeft.