Что такое трейты
Трейты (англ. 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 для доступа с свойствам базового класса.
-
В трейтах можно задавать абстрактные классы, которые должны быть реализованы в классах, использующих эти трейты.
-
К методам трейта можно обратиться напрямую, используя оператор двойного двоеточия.
Источники :
Нет Ответов