Løsning av metodekonflikter i traits i OOP i PHP
Siden én klasse kan bruke flere traits, kan vi støte på et problem som oppstår når to traits har metoder med samme navn.
I dette tilfellet vil PHP gi en fatal feil. For å rette opp situasjonen, må man løse navnekonflikten eksplisitt. La oss se hvordan dette gjøres i praksis.
La oss si at vi har to traits med den samme
metoden method:
<?php
trait Trait1
{
private function method()
{
return 1;
}
}
trait Trait2
{
private function method()
{
return 2;
}
}
?>
La oss også si at vi har en klasse Test
som bruker begge våre traits. Hvis man bare
kobler begge traits til klassen vår, vil
PHP gi en feil, fordi traitsene har
overlappende metoder:
<?php
// Denne koden vil gi en feil!
class Test
{
use Trait1, Trait2; // kobler til traits
}
?>
La oss løse navnekonflikten
mellom våre traits. For dette finnes en spesiell
operator insteadof. Ved hjelp av denne operatoren
skal vi bruke metoden method fra trait
Trait1 i stedet for den samme metoden fra trait
Trait2:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
}
new Test;
?>
Som du ser, er syntaksen som følger: først
trait-navnet, deretter to koloner, deretter metodenavnet,
deretter vår operator insteadof
og navnet på det andre traitet.
La oss teste:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
public function __construct()
{
echo $this->method(); // vil vise 1, fordi dette er metoden fra det første traitet
}
}
new Test;
?>
Så, i klassen vår har vi sagt at hvis
metoden method brukes, bør
den hentes fra det første traitet. Man kan også gjøre omvendt
- ta metoden fra det andre traitet:
<?php
class Test
{
use Trait1, Trait2 {
Trait2::method insteadof Trait1;
}
public function __construct()
{
echo $this->method(); // vil vise 2, fordi dette er metoden fra det andre traitet
}
}
new Test;
?>
Uansett, hvis vi spesifiserer at vi skal bruke
metoden fra ett trait, blir metoden fra det andre traitet
utilgjengelig. Man kan bruke
metoden fra det andre traitet også, ved å gi det et nytt navn
via nøkkelordet as, slik:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method() + $this->method2(); // vil vise 3
}
}
new Test;
?>
Om ønsket kan man også gi nytt navn til metoden fra det første traitet:
<?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(); // vil vise 3
}
}
new Test;
?>
Man kan ikke bruke nøkkelordet as uten
å definere hovedmetoden via insteadof,
dette vil gi en feil:
<?php
// Denne klassen vil gi en feil:
class Test
{
use Trait1, Trait2 {
Trait1::method as method1;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method1() + $this->method2();
}
}
new Test;
?>
Lag 3 traits med navnene Trait1,
Trait2 og Trait3. La det i det første
traitet være en metode method som returnerer
1, i det andre traitet - en metode med samme navn,
som returnerer 2, og i det tredje
traitet - en metode med samme navn,
som returnerer 3.
Lag en klasse Test som bruker
alle tre traitsene vi har laget. Lag i
denne klassen en metode getSum som returnerer
summen av resultatene fra metodene til de tilkoblede traitsene.