Введение в трейты
Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy. Урок 51 из 91.
PHP поддерживает только одиночное наследование — class может расширять только один родительский class. Но что делать, если нужно совместно использовать функциональность в нескольких несвязанных class? Здесь на помощь приходят trait.
trait — это механизм повторного использования кода, который позволяет тебе define методы и свойства, которые можно вставить в несколько классов. Думай о trait как о копировании и вставке на уровне языка: код из trait становится частью класса, который его использует.
<?php
trait Timestampable {
private string $createdAt;
public function setCreatedAt(): void {
$this->createdAt = date('Y-m-d H:i:s');
}
public function getCreatedAt(): string {
return $this->createdAt;
}
}
class Article {
use Timestampable;
public function __construct(public string $title) {
$this->setCreatedAt();
}
}
$article = new Article("PHP Traits");
echo $article->getCreatedAt();
Ключевое слово use внутри class импортирует члены trait. Теперь Article имеет доступ к setCreatedAt() и getCreatedAt(), как если бы они были определены непосредственно в class.
Тот же trait можно использовать в совершенно несвязанных классах — в классе Comment, классе User или любом другом классе, которому нужна функциональность временных меток. Это решает ограничение одиночного наследования, позволяя совместно использовать код по горизонтали в иерархии классов.
Задание
ЛегкоДавайте создадим простую систему приветствий, демонстрирующую, как trait позволяет делиться функциональностью между несвязанными class. Вы создадите trait, предоставляющий возможность приветствия, а затем используете его в двух совершенно разных class.
Вы организуете свой код в трёх файлах:
Greetable.php: создайте trait с именемGreetable, который предоставляет функциональность приветствия. У trait должны быть:- private property
$greeting(string) - method
setGreeting(string $greeting), который stores сообщение приветствия - method
greet(), который returns сообщение приветствия
- private property
Person.php: создайте classPerson, который использует traitGreetable. Подключите файл trait и используйте promotion конструктора, чтобы определить public property$name. В конструкторе вызовитеsetGreeting(), чтобы установить приветствие в значение"Hello, I'm [name]".Robot.php: создайте classRobot, который также использует traitGreetable. Подключите файл trait и используйте promotion конструктора, чтобы определить public property$model. В конструкторе вызовитеsetGreeting(), чтобы установить приветствие в значение"Beep boop, I am model [model]".
В main.php подключите оба файла class. Вы получите два входных значения: имя человека и номер model робота. Создайте экземпляры обоих class и выведите их приветствия в отдельных строках.
Это демонстрирует мощь trait: Person и Robot — полностью несвязанные class без общего родителя, однако оба получают одинаковую функциональность приветствия через trait. Каждый class по-своему настраивает использование этой функциональности.
Попробуйте сами
<?php
require_once 'Person.php';
require_once 'Robot.php';
// Читать ввод
$name = trim(fgets(STDIN));
$model = trim(fgets(STDIN));
// TODO: Создать экземпляр Person с заданным именем
// TODO: Создать экземпляр Robot с заданной моделью
// TODO: Вывести приветствие Person
// TODO: Вывести приветствие Robot (на новой строке)
?>В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово $thisМетодыСвойстваКонструктор (__construct)Деструктор (__destruct)Повторение — простой калькулятор4Наследование
Основы наследованияКлючевое слово parent::Переопределение методовКлючевое слово finalАбстрактные классыПовторение — иерархия сотрудников7Инкапсуляция
Public, Protected, PrivateМодификаторы доступа подробноГеттеры и сеттерыСокрытие информацииПродвижение конструктора (8.0)Повторение — система учёта студентов2Пространства имён и автозагрузка
Введение в пространства имёнКлючевое слово useСтандарт автозагрузки PSR-4Автозагрузчик ComposerПовторение — структурированный проект5Интерфейсы и контракты
Введение в интерфейсыРеализация интерфейсовРеализация нескольких интерфейсовИнтерфейс и абстрактный классАннотация типов с интерфейсамиПовторение — калькулятор фигур8Магические методы
Введение в магические методы__toString и __debugInfo__get, __set, __isset, __unset__call и __callStatic__clone и клонирование объектов__serialize и __unserializeПовторение — пользовательская коллекция3Свойства классов
Свойства экземпляра и статические свойстваКонстанты в классахСтатические методы и свойстваПриватные и защищённые свойстваСвойства только для чтения (PHP 8.1)Повторение — менеджер банковского счёта6Полиморфизм
Повторение переопределения методовПолиморфизм через интерфейсыАннотации типов и объединённые типыПозднее статическое связываниеПовторение — обработчик платежей9Трейты
Введение в трейтыИспользование нескольких трейтовРазрешение конфликтов трейтовАбстрактные методы в трейтахТрейты и наследование12Паттерны проектирования, часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн ObserverПаттерн StrategyПотренируйтесь самостоятельно: Онлайн-компилятор PHP