JackShcherbakov
@JackShcherbakov

Где может понадобиться трейт в PHP?

[Я уже прочитал этот вопрос на тостере, но он мне не помог. Так что не надо удалять и жаловаться на вопрос за существование подобного вопрса. Спасибо за понимание.]
Здравствуйте!

Почитал про трейты, однако не понял, где это может пригодиться на практике. Окей, они экономят кол-во кода, но где на практике то это может пригодиться. Сделать наследование и все. Вот и экономия и красота. В каком же случае наследование будет предпочтительнее трейтам?

Почему в этом коде нельзя трейт Cat сделать подклассом от Animal и Tiger сделать подклассом от Cat. Все вполне логично.

Заранее выражаю огромную благодарность всем, кто поможет!
  • Вопрос задан
  • 185 просмотров
Решения вопроса 4
OKyJIucT
@OKyJIucT
Sunshine reggae
Там, где может понадобиться множественное наследование.
Ответ написан
Комментировать
webinar
@webinar Куратор тега PHP
Учим yii: https://youtu.be/-WRMlGHLgRg
Есть у Вас 20 классов унаследованных от разных классов и есть методы одинаковые. Вы выносите их в трейт.

В каком же случае наследование будет предпочтительнее трейтам?

Это две абсолютно разные вещи. Наследование дает множество благ, трейт только 1. Стоит ли использовать наследование, если надо всего лишь метод вынести для повторного использования?
Ответ написан
mashletov
@mashletov
Math.random()
Например, в Laravel есть trait SoftDelete, который добавляет меняет поведение ActiveRecord при удалении — на самом деле, не удаляя, а скрывая запись. Т.е. мы можем в нужных моделях использовать use SoftDelete. Тем самым можем подключать и комбинировать нужный функционал не плодя наследование.
Что-то типа:
class User {
    use SoftDelete, LogAllActions, ReadOnly; // надуманный пример есс-но
}


Плодить ради этого промежуточные классы?
Ответ написан
Комментировать
@novrm
Пример номер один - трейт для внедрение через сеттер и геттер сервис менеджера.
... или других сервисов в другие сервисы.

use Zend\ServiceManager\ServiceLocatorInterface;

/**
 * ServiceManagerAwareTrait trait.
 */
trait ServiceManagerAwareTrait
{
    /**
     * $serviceManager instance.
     * @var ServiceLocatorInterface
     */
    protected $serviceManager = null;

    /**
     * Set $serviceManager.
     *
     * @param  ServiceLocatorInterface $serviceManager
     * @return self
     */
    public function setServiceManager(ServiceLocatorInterface $serviceManager)
    {
        $this->serviceManager = $serviceManager;

        return $this;
    }

    /**
     * Retrieve $serviceManager.
     *
     * @return ServiceLocatorInterface $serviceManager
     */
    public function getServiceManager()
    {
        return $this->serviceManager;
    }

}


Номер два - наследовать вы можете только ОДИН класс, а трейтов - МИЛЛИОН и тележку...
Вот у вас есть сервис, который вы обязаны унаследовать от некого стандартного класса...
... но желаете добавить еще несколько методов...
Что тогда?
Стандартный класс - кем то написан и является неизменяемой частью некого модуля - править нельзя.
Нужно - унаследовать ДВА раза - один раз наследовать расширенный класс, другой раз - непосредственно от расширенного - наследовать рабочий класс...
... или использовать трейты - элегантное решение.

Правда - есть несколько но - говорят, что при внедрении сложного трейта - тяжело писать тесты, ну и старые версии php их не поддерживают...
А так - очень даже упрощает жизнь.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы