#7.20 php trait ООП Трейты (Примеси). Оператор разрешения конфликтов имен в трейтах insteadof
Primary tabs
Как и интерфейсы, трейты компенсируют недостотатки отсутствия множественного наследования классов в PHP. Обычно они содержат общие фрагменты кода для классов — например, реализующих одни и те же интерфейсы похожим или одинаковым образом.
Трейты объявляются при помощи ключевого слова trait, после которого следует имя трейта и его содержимое в фигурных скобках:
<?php
trait TraitName
{
//какой-то код
}
Как и обычные классы, трейты могут содержать различные свойства и методы. Они не используются напрямую, а влкючаются в другие классы с помощью ключевого слова use, после чего объект класса может использовать свойства и методы трейта, как свои собственные, обращаясь к ним с помощью this->. Например,
<?php
trait Eater
{
public function eat($food)
{
echo $this->name, " ест ", $food, "<BR>";
}
}
abstract class Animal
{
protected $name;
public function __construct($name)
{
$this->name = $name;
}
abstract public function eat($food);
}
class Cat extends Animal
{
use Eater;
}
class Dog extends Animal
{
use Eater;
}
$cat = new Cat("Барсик");
$dog = new Dog("Джэк");
$cat->eat("whiskas");
$dog->eat("pedigree");
При наследовании методы трейта, включенного в производный класс, переопределяют методы базового класса, а методы текущего класса переопределяют методы трейта.
Конфликтующие методы
Если класс включает два трейта, содержащих методы с одинаковыми именами, то для разрешения конфликта имен используется оператор insteadof в фигурных скобках после use, явно указывающий, какой именно метод нужно использовать:
<?php
trait A
{
public function calculate($a, $b)
{
return $a + $b;
}
}
trait B
{
public function calculate($a, $b)
{
return $a*$b;
}
}
class Calculator
{
use A, B
{
A::calculate insteadof B;
}
}
$calculator = new Calculator;
echo $calculator->calculate(2, 4);
Результат: 6
Для использования замещенного метода ему нужно задать новый псевдоним с помощью оператора as:
<?php
trait A
{
public function calculate($a, $b)
{
return $a + $b;
}
}
trait B
{
public function calculate($a, $b)
{
return $a*$b;
}
}
class Calculator
{
use A, B
{
A::calculate insteadof B;
B::calculate as multiply;
}
}
$calculator = new Calculator;
echo $calculator->calculate(2, 4), "<BR>";
echo $calculator->multiply(2, 4);
Результат:
6
8
- Log in to post comments
- 1136 reads
vedro-compota
Wed, 10/11/2023 - 15:33
Permalink
Как и интерфейсы, трейты
Проще говоря, трейты (примеси) позволяют "подмешать" в класс функционал без наследования.
В шутку это можно назвать "наследованием сбоку".
В отличии от единственного класса-родителя, при использовании трейтов функционал можно "брать" сразу из нескольких
_____________
матфак вгу и остальная классика =)