- Интерфейсы в ООП на PHP
- Попробуем на практике
- Замечание
- Интерфейсы объектов
- implements
- Константы (Constants)
- Примеры
- Интерфейс PHP
- Определение и использование интерфейсов
- PHP-интерфейс и абстрактные классы
- Для чего используются интерфейсы PHP
- Корректировка кода в будущем
- Лучшая структура программы
- Добавление всех важных функций
- Еще один в ООП PHP пример реализации интерфейса
Интерфейсы в ООП на PHP
Как вы уже знаете, абстрактные классы представляют собой набор методов для своих потомков. Часть этих методов может быть реализована в самом классе, а часть методов может быть объявлена абстрактными и требовать реализации в дочерних классах.
Представим себе ситуацию, когда ваш абстрактный класс представляет собой только набор абстрактных публичных методов, не добавляя методы с реализацией.
Фактически ваш родительский класс описывает потомков, то есть набор их публичных методов, обязательных для реализации.
Зачем нам такое нужно: чтобы при программировании совершать меньше ошибок — описав все необходимые методы в классе-родителе, мы можем быть уверенны в том, что все потомки их действительно реализуют.
Когда это поможет: пусть мы создадим наш класс-родитель и несколько потомков к нему. Если потом через некоторое время, например, через месяц, мы решим создать еще одного потомка, наверняка мы уже забудем детали нашего кода и вполне можем забыть написать реализацию какого-нибудь метода в новом потомке. Однако сам PHP не позволит потерять метод — и просто выдаст ошибку.
То же самое касается другого программиста, работающего с вашим проектом. Пусть код класса-родителя писали вы, а затем ваш коллега решил создать еще одного потомка. У вашего коллеги также не получится потерять парочку методов.
Есть, однако, проблема: фактически мы сделали наш класс-родитель для того, чтобы писать в нем абстрактные публичные методы, но мы сами или наш коллега имеем возможность случайно добавить в этот класс не публичный метод или не абстрактный.
Пусть мы хотим физически запретить делать в родителе иные методы, кроме абстрактных публичных. В PHP для этого вместо абстрактных классов можно использовать .
Интерфейсы представляют собой классы, у которых все методы являются публичными и не имеющими реализации. Код методов должны реализовывать классы-потомки интерфейсов.
Интерфейсы объявляются так же, как и обычные классы, но используя ключевое слово interface вместо слова class .
Для наследования от интерфейсов используется немного другая терминология: говорят, что классы не наследуют от интерфейсов, а их. Соответственно вместо слова extends следует использовать ключевое слово implements .
Нельзя создать объект интерфейса. Все методы интерфейса должны быть объявлены как public и не должны иметь реализации. У интерфейса могут быть только методы, но не свойства. Нельзя также сделать интерфейс и класс с одним и тем же названием.
Попробуем на практике
Давайте попробуем на практике. Решим задачу на фигуры из предыдущего рока, но уже используя интерфейсы, а не абстрактные классы.
Итак, теперь у нас дан интерфейс Figure :
Давайте напишем класс Quadrate , который будет реализовывать методы этого интерфейса:
Как это работает: если забыть реализовать какой-нибудь метод, описанный в интерфейсе, PHP выдаст нам фатальную ошибку. Давайте реализуем также класс Rectangle :
Сделайте класс Disk ( круг ), реализующий интерфейс Figure .
Замечание
Как уже было написано выше, не может быть интерфейса и класса с одинаковым названием. Это создает некоторые проблемы с придумыванием названий. Например, мы хотим сделать класс User , реализующий интерфейс User . Как мы видим, у нас конфликт имен. Для его разрешения, нужно или класс назвать по-другому, или интерфейс.
Общепринято в таком случае название интерфейса начать с маленькой буквы i , чтобы показать, что это интерфейс, а не класс. То есть в нашем случае мы сделаем интерфейс iUser , а реализовывать его будет класс User . Такой подход мы иногда будем применять в следующих уроках.
Интерфейсы объектов
Интерфейсы объектов позволяют создавать код, который указывает, какие методы должен реализовать класс, без необходимости описывания их функционала.
Интерфейсы объявляются так же, как и обычные классы, но с использованием ключевого слова interface. Тела методов интерфейсов должны быть пустыми.
Все методы, определенные в интерфейсы должны быть публичными, что следует из самой природы интерфейса.
implements
Для реализации интерфейса используется оператор implements. Класс должен реализовать все методы, описанные в интерфейсе; иначе произойдет фатальная ошибка. При желании классы могут реализовывать более одного интерфейса за раз, реализуемые интерфейсы должны разделяться запятой.
Замечание:
Класс не может реализовать два интерфейса, содержащих одноименную функцию, так как это повлечет за собой неоднозначность.
Замечание:
Интерфейсы могут быть унаследованы друг от друга, так же как и классы, с помощью оператора extends.
Замечание:
Сигнатуры методов в классе, реализующем интерфейс, должны точно совпадать с сигнатурами, используемыми в интерфейсе, в противном случае будет вызвана фатальная ошибка.
Константы (Constants)
Интерфейсы могут содержать константы. Константы интерфейсов работают точно так же, как и константы классов, за исключением того, что они не могут быть перекрыты наследующим классом или интерфейсом.
Примеры
Пример #1 Пример интерфейса
// Объявим интерфейс ‘iTemplate’
interface iTemplate
public function setVariable ( $name , $var );
public function getHtml ( $template );
>
// Реализуем интерфейс
// Это сработает нормально
class Template implements iTemplate
private $vars = array();
public function setVariable ( $name , $var )
$this -> vars [ $name ] = $var ;
>
public function getHtml ( $template )
foreach( $this -> vars as $name => $value ) $template = str_replace ( » , $value , $template );
>
// Это не будет работать
// Fatal error: Class BadTemplate contains 1 abstract methods
// and must therefore be declared abstract (iTemplate::getHtml)
// (Фатальная ошибка: Класс BadTemplate содержит 1 абстрактный метод
// и поэтому должнен быть объявлен абстрактным (iTemplate::getHtml))
class BadTemplate implements iTemplate
private $vars = array();
public function setVariable ( $name , $var )
$this -> vars [ $name ] = $var ;
>
>
?>
Пример #2 Расширяемые интерфейсы
interface b extends a
public function baz ( Baz $baz );
>
// Это сработает
class c implements b
public function foo ()
>
public function baz ( Baz $baz )
>
>
// Это не сработает и выдаст фатальную ошибку
class d implements b
public function foo ()
>
Пример #3 Множественное наследование интерфейсов
interface b
public function bar ();
>
interface c extends a , b
public function baz ();
>
class d implements c
public function foo ()
>
Пример #4 Интерфейсы с константами
interface a
const b = ‘Константа интерфейса’ ;
>
?php
// Выведет: Константа интерфейса
echo a :: b ;
// Вот это, однако, не будет работать, так как
// константы перекрывать нельзя.
class b implements a
const b = ‘Class constant’ ;
>
?>
Интерфейс, совместно с контролем типов, предоставляет отличный способ проверки того, что определенный объект содержит определенный набор методов. Смотрите также оператор instanceof и контроль типов.
Интерфейс PHP
В PHP ООП интерфейс — это класс, в котором все методы являются абстрактными и открытыми.
Быстро пробежимся по трем терминам, используемым в этом определении. Класс, абстрактный и открытый. Класс представляет собой шаблон или образец объекта, он является основой объектно-ориентированного программирования. Абстрактный — это специальный метод, который объявляется, но не имеет тела, только пустые скобки. Открытый — это модификатор доступа public , он связан с доступом к методам. Это означает, что он доступен из любого места: из этого класса, вне его пределов и из любого производного класса.
Интерфейс PHP представляет собой инструмент для создания надежного кода, определяющего методы, которые должны быть реализованы с помощью класса без определения обработки этих методов. Это мощная и простая концепция, используемая в объектно-ориентированном PHP . Для его создания используется ключевое слово interface , он определяется так же, как класс PHP . Методы, содержащиеся в нем, не имеют никакого функционала, но интерфейс задает, какие методы необходимы для других классов. Любой класс, наследующийся от интерфейса, должен содержать те же методы, которые содержатся в интерфейсе, иначе выдается ошибка.
В интерфейсе ООП PHP мы задаем только имена методов и их параметры, а реализованы они могут быть позже. Принято объявлять все методы интерфейса как public . Для реализации интерфейса используется ключевое слово implements . При необходимости класс может реализовать более одного интерфейса, между собой они разделяются запятой. Как и класс, интерфейс может содержать константы. Единственное отличие заключается в том, что они не могут быть переопределены в производном классе.
Определение и использование интерфейсов
Интерфейс определяется с помощью ключевого слова interface . Все методы в нем должны быть открытыми и абстрактными:
Это пустой интерфейс. Мы добавим в него абстрактный метод motion . Таким образом, мы создадим простой PHP 5 ООП интерфейс, который может быть реализован позже:
Этот интерфейс может быть реализован любым классом animal , все классы animal будут содержать метод motion . Давайте рассмотрим пример. Для реализации интерфейса мы используем ключевое слово implements :
class Lion implements animal < public function motion() < // Задайте здесь функционал этого метода для класса lion >> class Fish implements animal < public function motion() < // Задайте функционал этого метода для класса fish >>
PHP-интерфейс и абстрактные классы
Интерфейсы и абстрактные классы очень похожи по своей концепции. Они помогают в создании шаблонов для классов, которые будут использоваться в приложении. Согласно основам ООП PHP , они отличаются друг от друга следующим:
- В интерфейсе все методы являются абстрактными ( без реализации ). В абстрактном классе лишь некоторые методы являются абстрактными. Абстрактный класс должен содержать, по крайней мере, один абстрактный метод. Иначе это будет стандартный класс PHP ;
- В интерфейсе PHP все объявленные методы являются открытыми, а в абстрактном классе методы могут быть открытыми, частными или защищенными. Следовательно, для интерфейсов существует ограничение на использование модификаторов доступа, а в абстрактном классе таких ограничений нет;
- Класс может реализовать неограниченное количество интерфейсов. В то же время класс PHP может породить только один абстрактный класс;
- Вы должны переопределять все методы интерфейса, а в абстрактном классе у вас есть выбор: переопределять методы или оставить их без изменений;
- Интерфейсы имеют более строгие правила, чем абстрактные классы. Интерфейс PHP призван обеспечить определенную логику, он выступает в качестве пустой оболочки или шаблона для других классов.
Для чего используются интерфейсы PHP
Интерфейс помогает программисту мыслить в правильном направлении. С точки зрения PHP ООП , класс представляет собой шаблон, а объект — это набор возможностей. Мы в большей степени связаны с функционалом, что он делает, а не как он это делает. Поэтому мы определяем основной интерфейс, который является общим, а затем он реализуется, что помогает мыслить в правильном направлении.
Корректировка кода в будущем
Разработка на объектно-ориентированном PHP позволяет корректировать код в будущем, не затрагивая при этом основной функционал. При написании кода в будущем эти характеристики всегда будут учитываться, а затем включаться дополнительные функции, но это не окажет никакого влияния на основные характеристики уже существующих объектов.
Лучшая структура программы
Объектно-ориентированный PHP был реализован для улучшения структуры создаваемых приложений. Добавление интерфейсов в PHP способствует тому, что кодирование становится аккуратным и чистым. Интерфейсы препятствуют написанию кода, который трудно поддерживать и изменять. С помощью интерфейсов мы можем легко поддерживать и модифицировать код, что повышает эффективность работы программистов.
Добавление всех важных функций
С помощью интерфейсов PHP мы можем создавать базовый функционал, который может быть определен для различных объектов по-разному, а затем добавить другие функции, если это потребуется.
Еще один в ООП PHP пример реализации интерфейса
?> class Cake implements Recipe < public function methodology() < >>
В этом коде мы видим класс Cake , который реализует интерфейс Recipe .
Вадим Дворников автор-переводчик статьи « PHP interface »