Что такое трейты

Трейты (англ. 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 для доступа с свойствам базового класса.

  • В трейтах можно задавать абстрактные классы, которые должны быть реализованы в классах, использующих эти трейты.

  • К методам трейта можно обратиться напрямую, используя оператор двойного двоеточия.


Источники :

(1) https://klisl.com/php_traits.html

Tags

Нет комментариев

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.