Rezolvarea conflictelor metodelor traitelor în POO în PHP
Deoarece o clasă poate utiliza mai multe traituri, putem întâmpina o problemă care apare atunci când două traituri au metode cu același nume.
În acest caz, PHP va afișa o eroare fatală. Pentru a remedia situația, va trebui să rezolvăm conflictul de nume în mod explicit. Cum se face acest lucru - vom vedea în practică.
Să presupunem că avem două traituri cu aceeași
metodă method:
<?php
trait Trait1
{
private function method()
{
return 1;
}
}
trait Trait2
{
private function method()
{
return 2;
}
}
?>
Să presupunem că avem și o clasă Test,
care utilizează ambele traituri ale noastre. Dacă pur și simplu
conectăm ambele traituri la clasa noastră, atunci
PHP va afișa o eroare, deoarece traiturile au
metode care coincid:
<?php
// Acest cod va afișa o eroare!
class Test
{
use Trait1, Trait2; // conectăm traiturile
}
?>
Să rezolvăm conflictul de nume
al traiturilor noastre. Pentru aceasta există un operator
special insteadof. Cu ajutorul acestui operator
vom folosi metoda method a traitului
Trait1 în locul aceleiași metode a traitului
Trait2:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
}
new Test;
?>
După cum vedeți, sintaxa este următoarea: mai întâi
numele traitului, apoi două puncte, apoi numele
metodei, apoi operatorul nostru insteadof
și numele celui de-al doilea trait.
Să verificăm:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
public function __construct()
{
echo $this->method(); // va afișa 1, deoarece aceasta este metoda primului trait
}
}
new Test;
?>
Deci, în clasa noastră am spus că dacă
se folosește metoda method, atunci trebuie
să o luăm din primul trait. Se poate și invers
- să luăm metoda celui de-al doilea trait:
<?php
class Test
{
use Trait1, Trait2 {
Trait2::method insteadof Trait1;
}
public function __construct()
{
echo $this->method(); // va afișa 2, deoarece aceasta este metoda celui de-al doilea trait
}
}
new Test;
?>
În orice caz, dacă specificăm să folosim
metoda unui trait, atunci metoda celui de-al doilea trait
devine indisponibilă. Se poate folosi
și metoda celui de-al doilea trait, redenumind-o
prin cuvântul cheie as, astfel:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method() + $this->method2(); // va afișa 3
}
}
new Test;
?>
Dacă se dorește, se poate redenumi și metoda primului trait:
<?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(); // va afișa 3
}
}
new Test;
?>
Utilizarea cuvântului cheie as fără
definirea metodei principale prin insteadof
nu este permisă, acest lucru va afișa o eroare:
<?php
// Această clasă va afișa o eroare:
class Test
{
use Trait1, Trait2 {
Trait1::method as method1;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method1() + $this->method2();
}
}
new Test;
?>
Creați 3 traituri cu numele Trait1,
Trait2 și Trait3. Să existe în primul
trait o metodă method care returnează
1, în al doilea trait - o metodă cu același nume
care returnează 2, iar în al treilea
trait - o metodă cu același nume,
care returnează 3.
Creați o clasă Test care utilizează
toate cele trei traituri create de noi. Creați în
această clasă o metodă getSum care returnează
suma rezultatelor metodelor traiturilor conectate.