Что такое трейты
Трейты (англ. traits) — это механизм обеспечения повторного использования кода в языках с поддержкой единого наследования. В php трейты внедрены с версии 5.4.0.
Они позволяют разработчику повторно использовать наборы методов и свойств в нескольких независимых классах.
Трейт похож на класс, но создать экземпляр трейта невозможно. Он предназначен для группирования функционала, который потом используется в разных классах.
Пример использования
trait HelloWorld{
public function sayHello() {
return 'Привет ';
}
}
class NameMen{
public $name = 'Вася';
}
class GetInfo extends NameMen{
use HelloWorld;
public function getPiple(){
echo $this->sayHello() . $this->name;
}
}
$obj = new GetInfo();
$obj->getPiple(); //Привет Вася
Тут создается трейт HelloWorld с публичным методом sayHello(). Все точно так же как в обычном классе. Далее создаем два класса. Класс GetInfo наследует класс NameMen для того, чтобы получить доступ к его методам и свойствам с помощью ключевого слова extends. Точно так же класс получает такой доступ к свойствам и методам трейтов с помощью директивы use, после которой указывается название трейта.
Нужные для использования в классе трейты можно указать через запятую:
use trait1, trait2, trait3;
Приоритет методов при работе с трейтами.
-
члены из текущего класса переопределяют одноименные методы в трейте,
-
члены из трейта переопределяют унаследованные классом методы. То есть трейт имеет преимущество перед классом который наследуем.
Конфликты трейтов
Ошибки могут быть когда подключается несколько трейтов, содержащие одни и те же методы. Или когда класс наследует у другого класса с подключением трейта, который уже был подключен в родительском классе.
Для разрешения конфликтов необходимо использовать оператор insteadof при подключении трейтов для того, чтобы точно выбрать один из конфликтных методов.
trait Hello1{
public function sayHello() {
return 'Hello';
}
}
trait Hello2{
public function sayHello() {
return 'Привет';
}
}
class GetInfo{
use Hello1,Hello2{
Hello2::sayHello insteadof Hello1;
}
public function getPiple(){
echo $this->sayHello();
}
}
$obj = new GetInfo();
$obj->getPiple(); //Привет
Внутри тела «use» мы использовали ключевое слово insteadof, слева от которого указывается трейт, метод которого будем использовать и имя самого метода, которые разделяются двойным двоеточием. В правой части указывается имя трейта, метод которого должен быть заменён.
Если же второй одноименный метод (из другого трейта) нам тоже нужен, то можно применить псевдоним имени используя ключевое слово as:
use Hello1,Hello2{
Hello2::sayHello insteadof Hello1;
Hello1::sayHello as hel;
}
public function getPiple(){
echo $this->sayHello();
echo $this->hel();
}
Статические методы и свойства
Используются так же как и в классах:
trait HelloWorld{
static $age = 'Вася';
static function sayHello() {
echo 'Привет ';
}
}
class GetInfo{
use HelloWorld;
public function getPiple(){
echo $this->sayHello();
}
}
GetInfo::sayHello(); //Привет
echo GetInfo::$age; //Вася
Доступ к свойствам базового класса
В трейтах для доступа к свойствам базового класса можно использовать псевдопеременную $this.
Изменения прав доступа к методам трейта.
Внутри трейта мы можем использовать любой модификатор доступа (public, private, protected) для методов. Но, кроме этого, есть возможность в классе менять этот модификатор на другой. Для этого в теле use после слова as можно указать новый модификатор.
use someTrait {
someTrait::someMethod as private;
}
Константы связанные с трейтами
__CLASS__ — Имя класса. Это имя содержит название пространства имен, в котором класс был объявлен (например, FooBar). Обратите внимание, что начиная с PHP5.4 __CLASS__ также работает в трейтах. При использовании в методах трейтов __CLASS__ является именем класса, в котором эти методы используется.
__TRAIT__ — Имя трейта. Это имя содержит название пространства имен, в котором трейт был объявлен (например, FooBar).
trait HelloWorld{
static $name_trait = __TRAIT__;
}
class GetInfo{
use HelloWorld;
}
echo GetInfo::$name_trait; //HelloWorld
Итоги:
-
Трейты используются, когда нужно набор методов вставить в разные классы, они чем-то похожи на команду include.
-
Трейты объявляются используя ключевое слово trait, в классе использование трейта прописывается ключевым словом use.
-
В одном классе можно использовать несколько трейтов.
-
Невозможно создать самостоятельный экземпляр трейта.
-
Трейты можно использовать совместно с интерфейсами.
-
Конфликты имён в трейтах устраняется при помощи ключевого слова insteadof, которое замещает метод.
-
Замещённому методу можно присвоить псевдоним при помощи ключевого слова as.
-
При помощи ключевого слова as также можно изменить область видимости метода трейта в классе.
-
В трейте можно использовать псевдопеременную $this для доступа с свойствам базового класса.
-
В трейтах можно задавать абстрактные классы, которые должны быть реализованы в классах, использующих эти трейты.
-
К методам трейта можно обратиться напрямую, используя оператор двойного двоеточия.
Источники :
Нет Ответов