#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
- 226 reads
vedro-compota
Wed, 10/11/2023 - 15:33
Permalink
Как и интерфейсы, трейты
Проще говоря, трейты (примеси) позволяют "подмешать" в класс функционал без наследования.
В шутку это можно назвать "наследованием сбоку".
В отличии от единственного класса-родителя, при использовании трейтов функционал можно "брать" сразу из нескольких
_____________
матфак вгу и остальная классика =)