Подготовка за вашето PHP интервю Всичко, което сте искали да знаете за интерфейсите, съвместимостта на подписите и
Интерфейсите, появили се за първи път в PHP 5, отдавна са заели силно място в обектно-ориентираната (или по-правилно "ориентирана към класа"?) част на езика.Изглежда - какво може да бъде по-просто от интерфейса? „Сякаш клас, но не клас, не можете да създадете инстанция, а по-скоро договор за бъдещи класове, съдържа заглавките на публичните методи“ – нали, с тези думи най-често отговаряте на дежурния въпрос в интервю за това какво е интерфейс?
Не всичко обаче е толкова просто, колкото може да изглежда на начинаещ PHP програмист. Конвенционалните аналогии не работят, езиковото ръководство ви подвежда, неочаквани клопки дебнат в кода...
Три предишни части:
Какво може да съдържа един интерфейс?
Очевидно публични методи и без внедряване: веднага след заглавката (подписа) на метода трябва да го завършите с точка и запетая:
Малко по-малко очевиден (въпреки че е описан в ръководството) е фактът, че интерфейсът може да съдържа константи (само публични, разбира се!):
Защо константите в интерфейсите не се използват широко в индустриалния код, въпреки че понякога се използват? Причината е, че те не могат да бъдат заменени в производен интерфейс или в клас, който имплементира този интерфейс. Интерфейсните константи са най-постоянните константи в света :)
Какво не може да съдържа един интерфейс?
Нищо друго не може. С изключение на заглавките на публичните методи и публичните константи.
Не може да се включи в интерфейса:
- Всякакви имоти
- Непублични методи
- Приложени методи
- Непублични константи
Съвместимост на сигнатурата на метода
За да проучим допълнително интерфейсите, вие и аз трябва да научим за една важна концепция, която е незаслужено пренебрегната в ръководството за PHP: концепцията за „съвместимост на подписите“.
Сигнатурата е описание на функция (метод), което включва:
- Модификатор на достъп
- Име на функция (метод).
- Списък с аргументи, където за всеки аргумент:
- Тип
- Име
- Стойност по подразбиране
- или оператора "три точки".
Да предположим, че имаме две функции, A и B. Сигнатурата на функция B се счита за съвместима с A (редът е важен, връзката не е симетрична!) в строгия смисъл, ако:
Съвпадат идеално
B добавя аргументи по подразбиране към A
B стеснява обхвата на A
Сега, след като въведохме тези три прости правила за съвместимост на дефинициите, е много по-лесно да разберем допълнителните тънкости на интерфейсите.
Наследяване на интерфейса
Интерфейсите могат да се наследяват един от друг:
Наследният интерфейс наследява всички методи и константи, дефинирани в родителския интерфейс от родителския интерфейс.
В производен интерфейс можете да замените метод от родителския интерфейс. Но само при условие, че или неговият подпис ще съвпадне точно с подписа на родителя, или ще бъде съвместим (вижте предишния раздел):
PHP има ли множествено наследяване?
Ако ви бъде зададен такъв въпрос, не се колебайте да отговорите:"да". Един интерфейс може да наследява от няколко други интерфейса.
Сега видяхте всичко:
Правила за разрешаване на конфликтиСигнатурите на метода за множествено наследяване са точно същите, както видяхме по-горе:
Тънкостите на внедряването на интерфейси
Всъщност след всичко, което вече видяхте, това вече не са тънкости, а по-скоро малки нюанси.
Първо, наистина извличането на клас от интерфейс се нарича имплементация. Въпросът е, че вие не просто наследявате методи и константи, но трябва да имплементирате тези методи, които са посочени от подписи, да ги попълните с код:
Важен аспект, който отличава реализацията на интерфейс от наследяването от друг клас, е способността да се внедряват няколко интерфейса в един клас едновременно.
Какво става, ако различните интерфейси, които класът имплементира, имат един и същ метод (със същото име)? Вижте по-горе - както и при наследяване на интерфейси един от друг, трябва да се спазва принципът на съвместимост на подписите.
И да. Не се доверявайте на ръководството, което казва:
Сигнатурите на метода в клас, който имплементира интерфейс, трябва точно да съвпадат със сигнатурите, използвани в интерфейса, в противен случай ще бъде хвърлена фатална грешка.
Класът, изпълняващ интерфейса, трябва да използва точно същите сигнатури на метода, както са дефинирани в интерфейса. Ако не го направите, това ще доведе до фатална грешка.
Не е така, важи същото правило за съвместимост:
Интерфейсът клас ли е? За и против
Всъщност не. Интерфейсът си е интерфейс, той се различава от клас поне по това, че е невъзможно да се създаде "екземпляр на интерфейс".
И всъщност, да, те имат много общо в PHP:
- Интерфейсите, като класовете, могат да бъдат в пространство от имена.
- Интерфейсите, като класовете, могат да се зареждат чрез механизма за автоматично зареждане. Функцията за автоматично зареждане ще бъде предадено пълното имеинтерфейс (с пространство от имена).
- Всеки интерфейс има предварително дефинирана константа ThisInterface::class, съдържаща пълното му име
- Интерфейс, подобно на клас, може да участва отдясно в оператора instanceof
- Интерфейс, подобно на клас, може да бъде определен като тип в подсказване на типа (показващ типа на аргумент или върната стойност на функция)
Какво да прочетете вечерта преди важно интервю за работа?
Разбира се, езиковото ръководство:
Успех с интервюто и работата!
Hardcore conf в C++. Каним само професионалисти.
Чете сега
JS-PHP MVC интерфейс - обединяване на всичко
PHP - ООП или процедурен подход
Използвате ли наследяване на множество интерфейси в PHP?
Коментари 34
Оо ... далеч от първата година в PHP, но не знаех за наследяването на интерфейси. Искам да кажа, изобщо не мислех, че можете да правите разширения в интерфейса :) Някак си не го срещнах и не ми беше полезно. Ще го сложа в касичката със свръхнеобходими знания, в случай че имате нужда от тях.
Между другото, моля, посочете за коя версия на PHP говорите. И тогава те ще започнат да посочват типа int в аргументите на метода под 7-ма версия и ще бъдат много изненадани.
Благодаря за вниманието. Където и да е посочено друго, това се отнася за текущата стабилна версия на PHP. В момента се знае, че е PHP 7.1
Ако искате да се съсредоточите върху поведението в по-стари версии, обикновено го уточнявам отделно.
И курсът е същият.
Просто в света на PHP "най-новата" и "текущата" версия, за съжаление, са много различни.
Сега не съм толкова активен с клиентски сървъри, но никога не съм срещал сървър на трета страна със 7-ми клон. Само ако го поставят нарочно, а това, уви, не винагиМоже би. Най-големият проект на debian, за който просто няма 7-ма версия, трябва да живее на 5.6 :(
P.S. Знам за някои статистики, според които повечето сървъри са на 7-ма версия. В реалния свят статистиката не работи, за съжаление.
Живеем в едни различни „реални светове“.
Аз също съм разработчик, активно практикувам (включително на основната си работа). Да срещна PHP 5 някъде за мен е като да видя динозавър на улицата. Теоретично е възможно, разбира се, но на практика не се случва :)
Да те попитам защо си такъв? Какви скрити фобии преди PHP 7 ви карат?
Не, не, погрешно сте разбрали :) Лично аз съм за новите версии, особено когато носят толкова много полезни неща.
Може би аз съм такъв, но наистина не съм виждал "обикновени" проекти, създадени още в дните на 5-ти клон, които да бъдат съзнателно актуализирани до 7-ми. Те просто работят... и това е :)
"Редовен" - имам предвид блогове, малки магазини и т.н. проекти до 10k / ден.
И така, какво ви спира? $ sudo apt update и готово - вие сте на желаната "седморка".
Ако преди не сте имали класове, наречени Int или String, няма да има проблеми. Всичко просто ще работи както преди, само 3 пъти по-бързо и 2 пъти по-ефективно на паметта.
Ако е имало такива класове, преименувайте ги. Правете 10 минути. Добре добре, настройте тестов стенд, като клонирате боен, дайте му различен домейн и изпълнете всички тестове за приемане. 20 минути е добре.
Или аз нещо не разбирам?
Като за начало, всяка актуализация изисква проверка за разумност и евентуално някои поправки. Съгласен съм, 7-ми клон е относително съвместим с предишния, но все пак. Обновявах PHP версиите много пъти и мисля, че и вие, така че трябва да знаете, че има такивавнезапни инциденти, които е по-лесно да оставите така.
Някой трябва да плати за изразходваното време. Поне оценявам времето и усилията си и ще актуализирам малко хора безплатно. Защо клиент би платил за прасе в джоба? Той вече има VDS за абстрактни 1000 рубли / месец е неактивен.
Всъщност това е основната причина, поради която "простите" проекти могат да останат на 5-та версия за много дълго време. Докато актуализацията не е силно необходима, никой не го интересува.
Втората точка: актуализирането не винаги е възможно. Например, преди около година исках да актуализирам PHP 5.6 > 7 на Debian 7 на мой собствен проект. Но се оказа, че под тази ОС тя просто не съществува. Танцуването с тамбури е възможно, но защо ми трябва? Актуализацията не е критична, имам достатъчно производителност. Можете да актуализирате операционната система и след това да актуализирате PHP, но отново, защо са ми нужни тези проблеми?
Третата точка ви беше описана по-долу: ако смятате, че класът Int и String са всичко, което може да попречи на актуализацията, прочетете отново тази страница отново: http://php.net/manual/ru/migration70.incompatible.php
Веднъж актуализирах PHP 5.3 > 5.4 (привидно) на един сървър на уеб студио с куп малки проекти. И беше такъв ад, че накрая просто върнахме всичко обратно. Понякога надграждането просто не си струва.
Е, да, не трябва просто да правите актуализация, по-добре е смислено да актуализирате пакетите един по един, ако искате да актуализирате всичко наведнъж. Изведнъж нещо ще полети и тогава потърсете причината.
прочетете отново тази страница: http://php.net/manual/ru/migration70.incompatible.php
Слушайте, вече съм превел от 5 на 7 около две дузини проекти с различна сложност. Включително напълно уникални предмети. И никъде не съм имал проблеми и никъде не беше офлайн за повече от три минути и разходите за труд бяха повече от конвенционалнитеняколко човекодни.
Повтарям въпроса си: добре, какво правя погрешно? какво правя грешно Какво още не знам за PHP, какво знаете вие? Кажи ми, интересно е!
UPD Подкрепихте вашата карма, може да помогне :) Но моля, никога повече не публикувайте връзки за референтни връзки...