Можете ли вы помочь мне объяснить интерфейс PHP. Я понимаю, что основной момент заключается в том, что несколько классов могут реализовать одни и те же функции.
abstract class Plane { public function openDoors(); } interface Fliers { public function fly(); }
теперь позволяет использовать их
class Boeing747 extends Plane implements Fliers { public function fly() { // some stuff } public function openDoors() { // do something } }
а также
class Tweety implements Fliers{ public function fly() { // some stuff } }
В этом случае оба Boeing747 и Tweety могут реализовать интерфейс Fliers для доступа к публичной функции fly (). Однако во всех примерах, которые я вижу, функциональность не определена в интерфейсе, а скорее, когда она вызывается внутри самого метода класса.
Почему бы мне не просто определить fly () как отдельную функцию в каждом из Boeing747 и Tweety вместо использования интерфейса? Можете ли вы дать конкретный, базовый пример, где это было бы выгодно? Благодаря!
Это метод, известный как « Дизайн по контракту» . По сути, интерфейс служит контрактом или обещанием, что любой класс, реализующий интерфейс, будет демонстрировать определенный набор способов поведения. Это позволяет вашему коду проверять возможности объекта, переданного ему, не беспокоясь о деталях, которые не имеют значения в текущем контексте. Например, ваш метод openDoors () может в равной мере примениться к дому, к самолету, к канальному замку, к машине или к чему-либо еще с дверями, но кроме наличия дверей все эти вещи имеют очень мало общего. Даже если они все поддерживают идею создания дверей, которые могут быть открыты, они могут фактически выполнять действия по открытию дверей совершенно разными способами.
Интерфейс позволяет вам рассказать код вызова, что все эти вещи имеют двери, которые вы можете открыть, без необходимости навязывать какие-либо искусственные отношения между ними, когда их не существует. Ключевое слово instanceof позволяет проверить, соответствует ли объект определенным критериям (если это экземпляр определенного класса или подкласса, или если он реализует конкретный интерфейс).
interface ThingWithDoors { public function openDoors (); } class House implements ThingWithDoors { // Implement openDoors here } class CanalLock implements ThingWithDoors { // Implement openDoors here } class Boeing747 extends Aircraft implements ThingWithDoors { // Implement openDoors here } // Calling code if ($object instanceof ThingWithDoors) { // We don't know exactly what class we have, but we do know it has an openDoors method $object -> openDoors (); }
Теоретически вы могли бы достичь такого же результата с другими функциями PHP, такими как method_exists или Reflection, но эти методы далеки от идеала, потому что нет контракта на принудительное исполнение (два разных класса могут реализовать открытие двери, но имеют совершенно разные имена для методов, которые делают это, и вам нужно будет проверить оба с вызовами method_exists). Затем предположим, что какой-то другой программист добавляет новый класс в систему, которая реализует открытие двери совершенно по-другому, чем те, которые вы уже проверяете. Весь код, в котором двери могут быть открыты во всей программе, должен быть обновлен, чтобы учитывать этот новый метод! Однако, если вы добавите новый класс в систему и реализуете интерфейс ThingWithDoors, тогда весь код, который открывает двери, автоматически будет работать с новым классом, как и со старым классом, без каких-либо изменений (при условии, что новый класс реализует интерфейс правильно и уважает возвращаемые значения, которые, к сожалению, не выполняются с помощью интерфейсов PHP).
Еще одна приятная вещь для программиста заключается в том, что им не нужно искать в документации / исходном коде, как вызвать определенные поведения в объекте. Если они знают, как выглядит интерфейс ThingWithDoors, то они знают, что все, что реализует ThingWithDoors, может открывать свои двери и что метод требует сделать это всегда будет openDoors (). Это может сэкономить вам немного времени в качестве разработчика, особенно на большом проекте!
в OO PHP объект может иметь только один родительский класс. Чтобы понять, почему это принято, позвольте использовать класс Bird, чтобы показать, какое множественное наследование и как оно может привести к проблемам.
Если вы хотите создать класс Wooping_Crane , имеет смысл вывести этот класс из класса Bird. Предположим, у вас также есть класс Endangered_Species .
Множественное наследование позволит вам создать класс Wooping_Crane из комбинации этих двух классов (классы Bird и Endangered). Это, казалось бы, отличная идея, пока вы не поймете, что оба класса определяют поведение в еде. Какой из них предпочтительнее? так что это недостаток множественного наследования.
PHP решает это двумя способами: во-первых, используя интерфейс – класс с определением функции.
Если Endangered_Species были интерфейсом, а не классом, использование нескольких функций приема не имело бы значения. Определение метода в классе Bird будет действовать как реализация функции интерфейса. Таким образом, интерфейсы избегают проблемы определения одной и той же функции дважды.
Во-вторых, используя черты . ou может прочитать об этом в других сообщениях.