Решавање на конфликти на методи на трејтови во ООП во PHP
Бидејќи една класа може да користи неколку трејтови, може да наидеме на проблем кој се појавува кога два трејта имаат методи со исто име.
Во овој случај, PHP ќе испушти фатална грешка. За да се поправи ситуацијата, ќе треба експлицитно да се реши конфликтот на имиња. Како се прави ова - ќе видиме во пракса.
Нека имаме два трејта со ист
метод method:
<?php
trait Trait1
{
private function method()
{
return 1;
}
}
trait Trait2
{
private function method()
{
return 2;
}
}
?>
Нека имаме и класа Test,
која ги користи двата наши трејта. Ако едноставно
ги поврземе двата трејта во нашата класа, тогаш
PHP ќе испушти грешка, бидејќи трејтовите имаат
методи кои се совпаѓаат:
<?php
// Овој код ќе испушти грешка!
class Test
{
use Trait1, Trait2; // ги поврзуваме трејтовите
}
?>
Ајде да го решиме конфликтот на имиња
на нашите трејтови. За ова постои специјален
оператор insteadof. Со помош на овој оператор
ќе го користиме методот method на трејтот
Trait1 наместо истиот метод на трејтот
Trait2:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
}
new Test;
?>
Како што гледате, синтаксата е следна: прво
името на трејтот, потоа две точки, потоа името
на методот, потоа нашиот оператор insteadof
и името на вториот трејт.
Ајде да провериме:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
public function __construct()
{
echo $this->method(); // ќе испринта 1, бидејќи ова е методот на првиот трејт
}
}
new Test;
?>
Значи, во нашата класа рековме дека ако
се користи методот method, тогаш
треба да се земе од првиот трејт. Може и обратно
- да се земе методот на вториот трејт:
<?php
class Test
{
use Trait1, Trait2 {
Trait2::method insteadof Trait1;
}
public function __construct()
{
echo $this->method(); // ќе испринта 2, бидејќи ова е методот на вториот трејт
}
}
new Test;
?>
Во секој случај, ако наведеме да се користи
методот на еден трејт, тогаш методот на вториот трејт
станува недостижен. Може да се користи
и методот на вториот трејт, преименувајќи го
преку клучното збор as, вака:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method() + $this->method2(); // ќе испринта 3
}
}
new Test;
?>
По желба, може да се преименува и методот на првиот трејт:
<?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(); // ќе испринта 3
}
}
new Test;
?>
Користењето на клучното збор as без
дефинирање на главниот метод преку insteadof
не е дозволено, ова ќе испушти грешка:
<?php
// Оваа класа ќе испушти грешка:
class Test
{
use Trait1, Trait2 {
Trait1::method as method1;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method1() + $this->method2();
}
}
new Test;
?>
Направете 3 трејта со имиња Trait1,
Trait2 и Trait3. Нека во првиот
трејт има метод method кој враќа
1, во вториот трејт - истоимен
метод, кој враќа 2, а во третиот
трејт - истоимен метод,
кој враќа 3.
Направете класа Test, која користи
сите три направени од нас трејтови. Направете во
оваа класа метод getSum, кој враќа
збир од резултатите на методите на поврзаните трејтови.