Наследование интерфейсов

Лабораторная работа №8. Интерфейсы и трейты.

До сих пор мы подразумевали, что у каждого производного класса может быть только единственный базовый. Наследовать свойства и методы сразу нескольких классов (например, писать class А extends в, с, D) в РНР нельзя.

Большинство современных языков программирования (Java, С# и т. д.) отказались от реализации множественного наследования, потому что она очень усложняет логику программы и добавляет много неоднозначностей в код.

Однако окружающий нас мир не укладывается в рамки иерархических моделей, а если и укладывается, то с большим трудом. Поэтому, несмотря на отказ от множественного наследования, все языки, поддерживающие объектно-ориентированный подход, предоставляют либо саму возможность множественного наследования (С++, Perl), либо какие-то компенсационные механизмы. РНР следует второму пути и предоставляет их целых два: интерфейсы и трейты.

Интерфейсы

Вернемся к схеме страниц, которую мы рассматривали в предыдущей работе.

Допустим, нам необходимо добавить на страницу, помимо заголовка, дополнительную SЕО-информацию: ключевые слова, МЕТА-описание страницы, оg-теrи для социальных сетей. Причем добавлять эту информацию на уровне класса Page может оказаться не очень разумной тактикой, т. к. ряд страниц, например User, точно не будут снабжаться SЕО-информацией. Часть страниц будет снабжаться ею лишь избрано.

Мы могли бы добавить SЕО-информацию на уровне класса Cached, однако класс несет совсем другую функцию и его нужно переименовывать. Кроме того, у нас получается ограничение, что любая кэшируемая страница снабжается SЕО-информацией, и наоборот, если мы захотим кэшировать страницу, то в нагрузку мы получим SЕО-блок.

Для решения данной проблемы предназначены интерфейсы. Интерфейс (interface) представляет собой обычный абстрактный класс, но только в нем не может быть свойств, и, конечно, не определены тела методов. Фактически некоторый интерфейс указывает лишь список методов, их аргументы и модификаторы доступа (обычно только protected и puЬlic). Допускается также описание констант внутри интерфейса (ключевое слово const).

Класс, реализующий некоторый интерфейс, обязан содержать в себе определения всех методов, заявленных в интерфейсе. Это объясняет, почему в мире ООП интерфейс часто называют контрактом: любой класс, "подписавшись в контракте", обязуется "выполнять" его "условия". Если хотя бы один из методов не будет реализован, вы не сможете создать объект класса: возникнет ошибка.

Главное достоинство интерфейсов заключается в том, что класс может реализовывать интерфейсы независимо от основной иерархии наследования (рис. 1).

Рис. 1. Интерфейс seo реализуют лишь, те классы, где он требуется

Более того, класс может реализовывать сразу несколько интерфейсов. Например, диаграмму на рис. 1 можно расширить интерфейсом тегов (Tаg): страницы, снабженные тегами, выводят в конце их список. Теги представляют собой гиперссылки, которые ведут к списку материалов, снабженных такими же тегами (рис. 2).

Рис. 2. Реализация сразу нескольких интерфейсов

Для "привязки" интерфейсов к классу используется ключевое слово implements:

Теперь каждый класс, который расширяет интерфейсы Seo или Tаg, обязан реализовать абстрактные методы, заданные на уровне интерфейса, в противном случае РНР выдаст сообщение об ошибке.

Интерфейс рассматривается как абстрактный класс. Проверить, реализует ли текущей класс интерфейс, можно при помощи оператора instanceof, коrорый мы рассмотрели в предыдущей работе.

Наследование интерфейсов

Интерфейсы, так же как и обычные классы, могут наследовать друг друга. Например, от интерфейса Tag можно унаследовать интерфейс для списка авторов Author новостного материала (рис. 3).

Для наследования в интерфейсах, так же как и в классах, используется ключевое слово extends (листинг 1).

Рис. 3. Интерфейсы могут наследовать друг другу

Листинг 1 Наследование интерфейсов. Файл ifacemulti.php

Обратите внимание на одну деталь. Интерфейс Tаg расширяется интерфейсом Author, который, в свою очередь, реализуется классом News. Если попробовать расширить класс News интерфейсом Tаg напрямую, будет возвращена ошибка.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: