Приветствую всех в третей, заключительной, части минисериала ” Сущности ООП”. Здесь я буду повествовать об интерфейсах и трейтах(что следует с названия) – что это? зачем? как использовать?
Интерфейсы
С этого сайта: интерфейс — это класс, в котором все методы являются абстрактными и открытыми. Определение, которое даю я на тех.собеседованиях(исходя из своего понимания) – интерфейс – это карта публичных свойств и методов класса, который будет его реализовывать.
Свойства интерфейсов
Как сказал ранее – он определяет публичные свойства(исключая тело метода, только имя и параметры) и методы класса. Также, он определяет константы класса и, в отличии от полей, они могут принимать значения в самом интерфейсе; затем эти константы будут доступны в классе-реализаторе.
<?php interface B { const A = 1; function rr(); } interface C { function drr(); } interface D extends B,C { } class Page implements D { function __construct() { echo self::A; } function rr() { } function drr() { } } new Page(); /* Вывод: 1 Process finished with exit code 0
В коде выше(PHP) приведено еще одно свойство интерфейсов – множественное наследование. Несмотря на то, что это карта класса, конечный класс может содержать иные, как публичные, так и скрытые методы и поля.
Разница между абстрактным классом и интерфейсом
Первое – это разные сущности – соответственно, срои сущностные особенности – это и очевидного… Следующее – это то, что в абстрактном классе могут быть реализованные методы. В целом, это все отличия.
Цель интерфейсов – задание определенных свойств для классов реализаторов, используеться для обеспечения гибкости кода путем следования некоторым принципам SOLID.
Трейты
Трейт – это механизм обеспечения повторного использования кода в языках с поддержкой только одиночного наследования определение от разработчиков PHP. По сути, это решение-костыль для языков с одиночным наследованием, но где хочется/нужно наследовать больше кода; т.е. трейт не может быть инициализирован в объект(как и интерфейс, и абстрактный класс), что, также, означает, что трейт без класса ничто(как и интерфейс, в общем-то…).
Свойства
Здесь речь будет не о том, что можно сделать в трейте, а о том как клас вращает трейты. Почему же о классах? – потому как в трейте можно только объявлять методы, свойства и константы. Нет, соврал… трейт может использовать трейт(строка 12), также содержать абстрактные и статические методы и свойства.
Итак, о классах… начнем с того, что можно подмешивать в класс более одного трейта(строка 23). При этом методы и свойства одного метода доступны в другом(если они публичны, строка 6). Об области видимости – она такая же как у классов, с теми же модификаторами.
<?php trait A { public function ff() { echo $this->b; } } trait B { use C; public $b; protected function ff() {} } trait C {} class Page { use A, B { A::ff insteadof B; b as private; } }
Теперь пару строк о структуре после перечисления используемых трейтов(строки 23 – 26). Поскольку в двух примесях есть метод с одинаковым названием – возникает конфликт и код выкинет фатальную ошибку. Строка 24 говорит о том, что в классе нужно отдать предпочтение методу с трейта А(A::ff
вместо B
); аналогично работает и для свойств. Строка 25 – изменение видимости свойства/метода.
Как уже отмечалось ранее, цель – это способ осуществления множественного наследования там, где оно недоступно на прямую.