интерфейс php зачем нужен

Готовимся к собеседованию по PHP: Всё, что вы хотели узнать об интерфейсах, совместимости сигнатур и не побоялись узнать

интерфейс php зачем нужен. 9b92884f0c7c49599d874f02890c19d3. интерфейс php зачем нужен фото. интерфейс php зачем нужен-9b92884f0c7c49599d874f02890c19d3. картинка интерфейс php зачем нужен. картинка 9b92884f0c7c49599d874f02890c19d3. Интерфейсы, впервые появившись в PHP 5, давно уже заняли прочное место в объектно-ориентированной (или всё-таки правильнее «класс-ориентированной»?) части языка.Интерфейсы, впервые появившись в PHP 5, давно уже заняли прочное место в объектно-ориентированной (или всё-таки правильнее «класс-ориентированной»?) части языка.

Казалось бы — что может быть проще интерфейса? «Как бы класс, но и не класс, нельзя создать экземпляр, скорее контракт для будущих классов, содержит в себе заголовки публичных методов» — не правда ли, именно такими словами вы чаще всего отвечаете на собеседовании на дежурный вопрос о том, что такое интерфейс?

Однако не всё так просто, как может показаться начинающему программисту на PHP. Привычные аналогии не работают, руководство по языку вводит вас в заблуждение, в коде таятся неожиданные «подводные камни»…

Три предыдущие части:

Что может содержать интерфейс?

Очевидно, что публичные методы, причем без реализации: сразу после заголовка (сигнатуры) метода следует закончить его точкой с запятой:

Чуть менее очевиден (хотя и описан в мануале) тот факт, что интерфейс может содержать константы (разумеется, только публичные!):

Почему же константы в интерфейсах не получили широкого распространения в промышленном коде, хотя и используются иногда? Причина в том, что их невозможно переопределить в интерфейсе-наследнике или в классе, реализующем данный интерфейс. Константы интерфейсов — самые константные константы в мире 🙂

Чего не может содержать интерфейс?

Больше ничего не может. Кроме заголовков публичных методов и публичных констант.

Нельзя включать в интерфейс:

Совместимость сигнатур методов

Для дальнейшего изучения интерфейсов нам с вами нужно узнать о важнейшем понятии, которое незаслуженно обойдено вниманием в мануале по PHP: о понятии «совместимости сигнатур».

Сигнатура — это описание функции (метода), включающее в себя:

Предположим, что у нас есть две функции, A и B.
Сигнатура функции B считается совместимой с A (порядок важен, отношение несимметрично!) в строгом смысле, если:

Они полностью совпадают

Тривиальный случай, комментировать тут нечего.

B добавляет к A аргументы по умолчанию

B сужает область значений A

Теперь, когда мы ввели эти три простых правила совместимости определений, станет гораздо проще понять дальнейшие тонкости, связанные с интерфейсами.

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

Интерфейсы могут наследоваться друг от друга:

Интерфейс-наследник получает от интерфейса-предка в наследство все определенные в предке методы и константы.

В интерфейсе-наследнике можно переопределить метод из родительского интерфейса. Но только при условии, что либо его сигнатура будет в точности совпадать с сигнатурой родительского, либо будет совместима (см. предыдущий раздел):

Если ли в PHP множественное наследование?

Если вам зададут такой вопрос, смело отвечайте: «да». Интерфейс может наследоваться от нескольких других интерфейсов.

Теперь вы видели всё:

Правила решения конфликтов сигнатур методов при множественном наследовании точно такие же, как мы уже видели выше:

— либо сигнатуры совпадают полностью
— либо сигнатура метода интерфейса, упомянутого в списке предков первым, должна быть совместима с сигнатурой из второго предка (да, порядок упоминания имеет значение, но это очень редкий кейс, просто не принимайте его никогда во внимание)

Тонкости реализации интерфейсов

Собственно, после всего, что вы уже видели, это уже и не тонкости, а так, мелкие нюансы.

Во-первых действительно, наследование класса от интерфейса называется реализацией. Смысл в том, что вы не просто получаете в наследство методы и константы, но обязаны реализовать те методы, которые заданы сигнатурами, наполнить их кодом:

Важный аспект, который отличает реализацию интерфейса от наследования от другого класса — это возможность реализовать в одном классе несколько интерфейсов сразу.

Как быть, если в разных интерфейсах, которые реализует класс, будет один и тот же метод (с одинаковым названием)? Смотри выше — также, как и при наследовании интерфейсов друг от друга должен соблюдаться принцип совместимости сигнатур.

И да. Не верьте мануалу, который провозглашает:

Сигнатуры методов в классе, реализующем интерфейс, должны точно совпадать с сигнатурами, используемыми в интерфейсе, в противном случае будет вызвана фатальная ошибка.

The class implementing the interface must use the exact same method signatures as are defined in the interface. Not doing so will result in a fatal error.

Всё не так, действует тоже самое правило совместимости:

Интерфейс — это класс? Pro et Contra

Вообще-то нет. Интерфейс — это интерфейс, он отличается от класса хотя бы тем, что нельзя создать «экземпляр интерфейса».

И вообще-то да, у них в PHP очень много общего:

Что почитать в ночь перед ответственным собеседованием?

Разумеется, мануал по языку:

Системный подход к самообразованию в программировании очень важен. И, по моему мнению, неплохо в начале пути в IT помогают структурировать самообучение вебинары и краткосрочные курсы. Именно поэтому я рекомендую (и немного скромно рекламирую) даже опытным разработчикам посещать разовые вебинары и курсы повышения квалификации — результат при грамотном сочетании курсов и самоподготовки всегда налицо!

Источник

Зачем нужны интерфейсы?

Друзья, неоднократно задавался вопросом и задавал вопрос здесь, беспокоит и не даёт покоя мысль о том, зачем нужны интерфейсы в php на пример.

Есть кучи примеров, где объяснятся лишь только то что, они задают жёстко типизированную структуру для других классов которые имплементируют и обязаны реализовывать публичные методы, но толку, неужели профит только в этом, бороздя статьи по интерфейсам были такие мнения что они позволяют обойти НЕмножественное наследование, то есть как? Объясните пожалуйста, элементарный пример связи, как это происходит?

Допустим есть интерфейс с одним методом. Имплементирующие его классы реализуют его под свои нужды как им хотелось бы, но везде по разному, и это всё? Допустим наследовались от того класса, который имплементировал интерфейс, дальше что?

Вернёт соответствующие строки, это и есть пример реализации интерфесов?

интерфейс php зачем нужен. dVTjR. интерфейс php зачем нужен фото. интерфейс php зачем нужен-dVTjR. картинка интерфейс php зачем нужен. картинка dVTjR. Интерфейсы, впервые появившись в PHP 5, давно уже заняли прочное место в объектно-ориентированной (или всё-таки правильнее «класс-ориентированной»?) части языка.

2 ответа 2

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками php интерфейс или задайте свой вопрос.

Связанные

Похожие

Подписаться на ленту

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

дизайн сайта / логотип © 2021 Stack Exchange Inc; материалы пользователей предоставляются на условиях лицензии cc by-sa. rev 2021.11.22.40798

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Источник

Интерфейсы в PHP

— это список методов, которые должны быть реализованы в наследующем интерфейс классе. Обращаю внимание, интерфейс — это лишь список методов.

Интерфейс может быть реализован в классе, правильно использовать именно это слово — «реализован», а не слово «унаследован».

Давайте расмотрим пример объявления интерфейса с именем Planes (самолёты) и его реализацию в классе Boing.

Класс Boing может содержать и другие методы, но он обязан реализовывать методы, прописанные в интерфейсе.

Интерфейсы очень похожи на абстрактные классы в PHP, но в отличии от них интерфейсы не содержат методов с телами, а представляют собой только список методов, который должен быть реальзован в классе, реализующем этот интерфейс.

В интерфейсах все методы фактически являются абстрактными, при этом ключевое слово abstract при задании методов в интерфейсе не используется.

Интерфейсы в PHP кроме списка методов, также могут содержать константы.

Вам должно быть известно, что в PHP множественного наследования нет, то есть один класс может наследовать только один класс. Но интерфейсы в PHP позволяют делать множественную реализацию, то есть один класс может реализовывать несколько интерфейсов.

Вот пример реализации в классе Boing двух интерфейсов:

Мы видим что реализуемые интерфейсы просто перечесляются через запятую:

Но польза от интерфейсов не только в том, что они определяют набор публичных методов, который должен быть в реализующих классах. Это безусловно очень полезно при работе команды программистов над крупным проектом.

У интерфейсов есть ещё одно полезное свойство, они присваивают объектам дополнительный тип.

Философия интерфейсов и абстрактных классов

Вы уже знаете, что в PHP есть два типа сущностей: интерфейсы и абстрактные классы. Они очень похожи, но кроме технических различий, нужно понимать разницу в идеологии их использования.

Интерфейсы предназначены для описания действий, которые может сделать объект.

Абстрактный класс описывает класс сущностей в целом, например автомобили. При помощи абстрактного класса можно указать, что автомобили имеют цвет, производителя, мощность, могут ездить, сигналить и т.д. А интерфейс предназначен только для описание методов управление, то есть в случае автомобиля это: газовать, тормозить, сигналить, включить фары и т.д.

Источник

В чем смысл интерфейсов в PHP?

Интерфейсы позволяют создавать код, который определяет методы классов, которые его реализуют. Однако вы не можете добавить код к этим методам.

Абстрактные классы позволяют делать то же самое, вместе с добавлением кода к методу.

Теперь, если вы можете достичь той же цели с абстрактными классами, почему нам даже нужна концепция интерфейсов?

Мне сказали, что это связано с теорией OO от C ++ к Java, на которой основывается OO-материал PHP. Является ли понятие полезным в Java, но не в PHP? Разве это просто способ удержания от заполнителей, заполненных абстрактным классом? Я что-то упускаю?

Вся точка интерфейса – предоставить вам гибкость, чтобы ваш класс был вынужден реализовать несколько интерфейсов, но все же не допускал множественного наследования. Проблемы с наследованием от нескольких классов много и разнообразны, и на странице википедии он суммирует их довольно хорошо.

Интерфейсы – это компромисс. Большинство проблем с множественным наследованием не применяются к абстрактным базовым классам, поэтому большинство современных языков в настоящее время отключает множественное наследование, но называет абстрактные интерфейсы базовых классов и позволяет классу «реализовывать» столько, сколько они хотят.

Концепция полезна повсюду в объектно-ориентированном программировании. Для меня я думаю о интерфейсе как о контракте. До тех пор, пока мой класс и ваш класс согласны с этим контрактом подписи этого метода, мы можем «взаимодействовать». Что касается абстрактных классов, то я вижу больше базовых классов, которые заглушают некоторые методы, и мне нужно заполнить детали.

Зачем вам нужен интерфейс, если уже есть абстрактные классы? Чтобы предотвратить множественное наследование (может вызвать множество известных проблем).

Одна из таких проблем:

«Проблема с алмазами» (иногда называемая «смертельным алмазом смерти») является двусмысленностью, которая возникает, когда два класса B и C, наследуемые от A и класса D, наследуются как от B, так и от C. Если в A существует метод, который B и C переопределены, и D не переопределяет его, то какая версия метода наследует D: B или C?

Что делает интерфейс для вас (почему кто-то даже использовал его)? Интерфейс не позволяет вам совершать «ошибки» (он гарантирует, что все классы, которые реализуют определенный интерфейс, будут иметь все методы, которые находятся в интерфейсе).

Например, он будет использоваться так (везде в нашем коде):

Таким образом, что-то подобное не может произойти:

Гораздо проще запомнить один интерфейс и использовать его везде, а не несколько разных.

Класс, реализующий интерфейс, должен реализовывать все методы, которые имеет интерфейс / имеет.

Надеюсь, что я не слишком много повторил.

Разница между использованием интерфейса и абстрактным классом имеет больше общего с организацией кода для меня, чем с помощью самого языка. Я много использую их при подготовке кода для других разработчиков, с тем чтобы они оставались в рамках предполагаемых шаблонов проектирования. Интерфейсы – это своего рода «дизайн по контракту», в соответствии с которым ваш код соглашается ответить на установленный набор вызовов API, которые могут исходить из кода, к которому у вас нет доступа.

Хотя наследование от абстрактного класса является отношением «является», это не всегда то, что вы хотите, а реализация интерфейса – это скорее отношение «действует как a». Это различие может быть весьма значительным в определенных контекстах.

Например, скажем, у вас есть абстрактная учетная запись класса, из которой расширяются многие другие классы (типы учетных записей и т. Д.). Он имеет определенный набор методов, которые применимы только к этой группе типов. Тем не менее, некоторые из этих подклассов учетной записи реализуют Versionable, Listable или Editable, поэтому их можно бросить в контроллеры, которые ожидают использования этих API. Контроллеру все равно, какой тип объекта он

Напротив, я также могу создать объект, который не распространяется на Учетную запись, скажем, на абстрактный пользовательский класс и все еще реализует Listable и Editable, но не Versionable, что здесь не имеет смысла.

Таким образом, я говорю, что подкласс FooUser НЕ является учетной записью, но они действуют как редактируемый объект. Аналогично, BarAccount распространяется из учетной записи, но не является подклассом User, но реализует Editable, Listable и также Versionable.

Добавление всех этих API для Editable, Listable и Versionable в само абстрактные классы не только было бы загроможденным и уродливым, но и дублировало бы общие интерфейсы в Account и User, или принудительно применило бы объект User для реализации Versionable, возможно, просто для того, чтобы исключение.

Интерфейсы по сути являются планом того, что вы можете создать. Они определяют, какие методы должен иметь класс, но вы можете создавать дополнительные методы вне этих ограничений.

Я не уверен, что вы подразумеваете, не имея возможности добавить код к методам – ​​потому что вы можете. Вы применяете интерфейс к абстрактному классу или классу, который его расширяет?

Метод в интерфейсе, примененном к абстрактному классу, должен быть реализован в этом абстрактном классе. Однако примените этот интерфейс к расширяющему классу, и этот метод нуждается только в реализации в расширяющемся классе. Я могу ошибаться здесь – я не использую интерфейсы так часто, как мог / должен.

Я всегда думал о интерфейсах как шаблоне для внешних разработчиков или о дополнительном наборе правил, чтобы убедиться, что все правильно.

Вы будете использовать интерфейсы в PHP:

и другие вещи, о которых я не могу сейчас думать

Номер 4 это, вероятно, самый очевидный вариант использования, с которым вы не можете обращаться с абстрактными классами.

От мышления в Java:

Интерфейс говорит: «Это будет выглядеть все классы, реализующие этот конкретный интерфейс». Таким образом, любой код, который использует определенный интерфейс, знает, какие методы могут быть вызваны для этого интерфейса, и все. Таким образом, интерфейс используется для установления «протокола» между классами.

Интерфейсы существуют не как база, на которой классы могут расширяться, а как карта требуемых функций.

Ниже приведен пример использования интерфейса, где абстрактный класс не подходит:
Допустим, у меня есть приложение календаря, которое позволяет пользователям импортировать данные календаря из внешних источников. Я бы написал классы для обработки импорта каждого типа источника данных (ical, rss, atom, json). Каждый из этих классов мог бы реализовать общий интерфейс, который обеспечивал бы, чтобы все они имели общие общедоступные методы, которые мое приложение должно получать.

Затем, когда пользователь добавляет новый канал, я могу определить тип фида и использовать класс, разработанный для этого типа, для импорта данных. Каждый класс, написанный для импорта данных для определенного фида, имел бы совершенно другой код, в противном случае между классами может быть очень мало сходства, кроме того, что им требуется реализовать интерфейс, который позволяет моему приложению их потреблять. Если бы я использовал абстрактный класс, я бы очень легко проигнорировал тот факт, что я не переопределил метод getEvents (), который бы тогда разорвал мое приложение в этом экземпляре, тогда как использование интерфейса не позволяло моему приложению запускаться, если ЛЮБОЙ из методов определенные в интерфейсе, не существуют в классе, который его реализовал. Моему приложению не нужно заботиться о том, какой класс он использует для получения данных из фида, только в том, что методы, необходимые для получения этих данных.

Чтобы сделать это еще дальше, интерфейс оказывается чрезвычайно полезным, когда я возвращаюсь к своему приложению календаря с целью добавления другого типа фида. Используя интерфейс ImportableFeed, я могу продолжить добавлять дополнительные классы, которые импортируют разные типы каналов, просто добавляя новые классы, реализующие этот интерфейс. Это позволяет мне добавить множество функций, не добавляя излишне объемную часть к моему основному приложению, поскольку мое основное приложение использует только доступные общедоступные методы, которые требуется интерфейсу, так как мои новые классы импорта фида реализуют интерфейс ImportableFeed, а затем я знаю, что я могу просто бросить его на место и продолжать двигаться.

Это очень простое начало. Затем я могу создать другой интерфейс, который может потребоваться для всех классов календаря, который предлагает больше функциональных возможностей, характерных для типа фида, который обрабатывает класс. Другим хорошим примером может служить метод проверки типа фида и т. Д.

Это выходит за рамки вопроса, но поскольку я использовал приведенный выше пример: Интерфейсы поставляются со своим набором проблем, если они используются таким образом. Мне нужно обеспечить вывод, который возвращается из методов, реализованных в соответствии с интерфейсом, и для этого я использую среду IDE, которая считывает блоки PHPDoc и добавляет возвращаемый тип в виде подсказки типа в блоке PHPDoc интерфейса, который затем перевести на конкретный класс, который его реализует. Мои классы, которые потребляют данные, выводимые из классов, реализующих этот интерфейс, будут, по крайней мере, знать, что ожидают массив, возвращенный в этом примере:

Существует не так много места для сравнения абстрактных классов и интерфейсов. Интерфейсы – это просто карты, которые при реализации требуют, чтобы класс имел набор открытых интерфейсов.

На мой взгляд, интерфейсы должны быть предпочтительнее над нефункциональными абстрактными классами. Я бы не удивился, если бы там было даже хитовую производительность, так как только один объект был создан, вместо того, чтобы разбирать два, объединив их (хотя, я не могу быть уверен, я не знаком с внутренней работой OOP PHP).

Верно, что интерфейсы менее полезны / значимы, чем по сравнению с, скажем, Java. С другой стороны, PHP6 представит еще больше намеков типа, включая подсказки типа для возвращаемых значений. Это должно добавить некоторое значение для интерфейсов PHP.

tl; dr: интерфейсы определяют список методов, которым необходимо следовать (think API), в то время как абстрактный класс дает некоторые базовые / общие функции, которые подклассы усовершенствуют для конкретных потребностей.

Интерфейсы предназначены не только для того, чтобы разработчики реализовали определенные методы. Идея состоит в том, что, поскольку у этих классов есть определенные методы, вы можете использовать эти методы, даже если вы не знаете фактический тип класса. Пример:

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

Динамически типизированные языки имеют понятие «утиная печать», где вам не нужны интерфейсы; вы можете предположить, что у объекта есть метод, который вы вызываете на него. Это работает вокруг проблемы в статически типизированных языках, где ваш объект имеет некоторый метод (в моем примере, read ()), но не реализует интерфейс.

Я не могу вспомнить, отличается ли PHP в этом отношении, но в Java вы можете реализовать несколько интерфейсов, но вы не можете наследовать несколько абстрактных классов. Я бы предположил, что PHP работает одинаково.

В PHP вы можете применять несколько интерфейсов, разделяя их запятой (я думаю, я не считаю это чистым soloution).

Что касается нескольких абстрактных классов, вы можете иметь несколько рефератов, расширяющих друг друга (опять же, я не совсем уверен в этом, но я думаю, что видел это где-то раньше). Единственное, что вы не можете продлить, – это последний класс.

Интерфейсы не дают вашему коду каких-либо повышений производительности или что-то в этом роде, но они могут пройти долгий путь, чтобы сделать его пригодным для обслуживания. Верно, что абстрактный класс (или даже не абстрактный класс) можно использовать для установления интерфейса к вашему коду, но правильные интерфейсы (те, которые вы определяете с ключевым словом и которые содержат только сигнатуры методов) просто проще сортировать и читать.

При этом я предпочитаю использовать дискретность при принятии решения о возможности использования интерфейса над классом. Иногда мне нужны реализации по умолчанию, или переменные, которые будут распространены во всех подклассах.

Конечно, вопрос о реализации с несколькими интерфейсами тоже звучит. Если у вас есть класс, который реализует несколько интерфейсов, вы можете использовать объект этого класса как разные типы в одном приложении.

Однако факт, что ваш вопрос о PHP, делает вещи немного интереснее. Встраивание в интерфейсы до сих пор не невероятно необходимо в PHP, где вы можете в значительной степени подавать что угодно любому методу, независимо от его типа. Вы можете статически вводить параметры метода, но некоторые из них повреждены (String, я считаю, вызывает некоторые икоты). Сопоставьте это с тем фактом, что вы не можете вводить большинство других ссылок, и нет никакой ценности в попытке заставить статическую типизацию в PHP ( на данном этапе ). И из-за этого значение интерфейсов в PHP на данный момент намного меньше, чем на более строго типизированных языках. Они имеют преимущество читаемости, но немного больше. Множественная реализация даже не выгодна, потому что вы все равно должны объявлять методы и предоставлять их органам внутри разработчика.

Ниже приведены точки для интерфейса PHP

Источник

PHP: как создать интерфейс и для чего они нужны?

Для полного понимания интерфейсов, вам нужно понимать объектно ориентированое программирование. Я покажу как создавать интерфейсы в PHP и для чего они могут пригодиться.

Для чего нужны интерфейсы

Если все что я написал выше, вам не понятно, то этой нормально, потому что я тоже сначала не понимал. Давайте посмотрим на простой пример класса и создадим на его примере интерфейс. Далее я буду подробно описывать что происходит с тем или иным участком кода.

Пример класса

Пример интерфейса

Давайте теперь возьмем Apple и свежесозданным интерфейсом:

Работает это следующим образом: у вас есть класс, который имлементирует Fruit интерфейс. Внутри него указаны какие методы должны быть у класса, которые будет его использовать. И если какой-то из них будет упущен, тогда PHP выдаст Exception (ошибку) и укажет что именно не так.

Давайте создадим новый класс с использованием Fruit интерфейса. Внутри класс будет лишь один метод, тем самым PHP должен выдать ошибку.

И теперь попробуйте открыть файл с этим классом. У вас должно вывести следующую ошибку:

Послесловие

Интерфейсы помогают определять структуру для классов. В дальнейшем вам будет проще понимать какие методы должны быть добавлены в класс благодаря им. Так же это прекрасный вариант для работы в команде — вы задали структуру в начале и каждый дальнейший разработчик будет видеть какая должна быть структура у класса.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *