экземпляр абстрактного класса php
Абстрактные классы
PHP 5 поддерживает определение абстрактных классов и методов. Класс, который содержит по крайней мере один абстрактный метод, должен быть определен как абстрактный. Следует помнить, что нельзя создать экземпляр абстрактного класса. Методы, объявленные абстрактными, несут, по существу, лишь описательный смысл и не могут включать реализации.
При наследовании от абстрактного класса, все методы, помеченные абстрактными в родительском классе, должны быть определены в классе-потомке; кроме того, область видимости этих методов должна совпадать (или быть менее строгой). Например, если абстрактный метод объявлен как protected, то реализация этого метода должна быть либо protected либо public, но никак не private. Более того, сигнатуры методов должны совпадать, т.е. контроль типов (type hint) и количество обязательных аргументов должно быть одинаковым. К примеру, если в дочернем классе указан необязательный параметр, которого нет в сигнатуре абстрактного класса, то в данном случае конфликта сигнатур не будет. Это правило также применяется к конструкторам начиная с версии PHP 5.4, ранее сигнатуры конструкторов могли отличаться.
Пример #1 Пример абстрактного класса
class ConcreteClass1 extends AbstractClass
<
protected function getValue () <
return «ConcreteClass1» ;
>
class ConcreteClass2 extends AbstractClass
<
public function getValue () <
return «ConcreteClass2» ;
>
Результат выполнения данного примера:
Пример #2 Пример абстрактного класса
class ConcreteClass extends AbstractClass
<
Результат выполнения данного примера:
Код, предназначенный для прежних версий PHP, должен работать без изменений, если в нём отсутствуют классы или функции, именованные ‘abstract’.
Абстрактные классы в ООП на PHP
Для этого существуют так называемые классы. Абстрактные классы представляют собой классы, предназначенные для наследования от них. При этом объекты таких классов нельзя создать.
Для того, чтобы объявить класс абстрактным, нужно при его объявлении написать ключевое слово abstract :
Попытка создать объект класса User вызовет ошибку:
Абстрактные методы
Давайте попробуем на практике. Пусть предполагается, что все потомки класса User должны иметь метод increaseRevenue ( увеличить доход ).
Этот метод должен брать текущий доход пользователя и увеличивать его на некоторую величину, переданную параметром.
Фишка тут в том, что абстрактный метод класса User заставляет программиста реализовывать этот метод в потомках, иначе PHP выдаст ошибку. Таким образом вы, или другой программист, работающий с вашим кодом, никак не сможете забыть реализовать нужный метод в потомке.
Итак, давайте попробуем на практике. Добавим абстрактный метод increaseRevenue в класс User :
Давайте теперь напишем реализацию метода increaseRevenue в классе Employee :
Проверим работу нашего класса:
Некоторые замечания
При наследовании от абстрактного класса, все методы, помеченные абстрактными в родительском классе, должны быть определены в дочернем классе.
Объявления методов также должны совпадать: количество обязательных параметром должно быть одинаковым. Однако класс-потомок может добавлять необязательные параметры, которые не были указаны при объявлении метода в родителе.
Практика
Пусть нам необходимо работать с геометрическими фигурами, например, с квадратами, прямоугольниками, треугольниками и так далее. Пусть каждая фигура будет описываться своим классом, при этом мы хотим сделать так, чтобы каждый класс имел метод для вычисления площади и метод для вычисления периметра фигуры.
Почему класс Figure абстрактный: потому что он не описывает реально существующую геометрическую фигуру и, соответственно, объект этого класса мы не будем создавать.
Почему методы getSquare и getPerimeter абстрактные: потому что каждая фигура имеет свой алгоритм вычисления площади и периметра и, соответственно, класс Figure не может написать реализацию этих методов.
Зачем нам вообще нужен класс Figure : чтобы наследовать от него и таким образом заставить всех наследников реализовать указанные методы.
Итак, напишем реализацию класса Figure :
Пусть теперь мы хотим создать класс Quadrate для описания геометрической фигуры квадрат. Как известно, у квадрата все стороны равны, поэтому для описания квадрата нам нужно задать только его ширину.
Давайте теперь унаследуем наш класс Quadrate от класса Figure :
Сейчас наша реализация класса Quadrate не рабочая, так как мы не написали реализацию абстрактных методов родителя.
Давайте сделаем это:
Давайте создадим квадрат со стороной 2 и найдем его площадь и периметр:
Усложним
Этот метод уже будет не абстрактный, а иметь реализацию, и все потомки смогут воспользоваться этим методом.
Почему мы можем написать реализацию этого метода прямо в классе Figure : потому что этот метод будет одинаковым для всех потомков.
Итак, добавим наш метод:
Применим наш метод:
Зачем нужны абстрактные классы и интерфейсы в php?
Абстрактный класс- это реальные инструменты, необходимые для
1) повышения Читабельности кода
2) Уверенности в том, что делает код
Далее уже сделать имплементацию этого интерфейса на всех наследниках класса Tariff где нужно, и не парится, что через какое-то время другой разработчик создаст новую реализацию тарифа и с твоего кода посыпятся баги
Да, носят чисто декларативный характер
Ruslan Ruslanov, не для упрощения кода, а для стандартизации взаимодействия между объектами. Если на вашем компе есть юсб вход, то и мышка вам нужна с таким же интерфейсом. В данном случае юсб это стандарт для ваших объектов, соблюдая который вы можете взаимодействовать их.
Попробуйте написать классы для этого примера.
С интерфейсами самый простой кейс:
1) Пишем какую-то функцию, которая принимает в качестве аргумент интерфейс.
2) Функция работает с методами интерфейса и получает какой-то результат.
3) Где-то есть отдельная логика, выбора конкретной реализации класса, который выполняет интерфейс.
Т.е. допустим, у нас есть онлайн-касса и есть 20 методов платежей. Сама онлайн-касса работает с интерфейсом проводки платежа, а как проводить платежи реализовано в конкретных классах платежных систем.
Из минусов, иногда приходиться весьма «изящно» натягивать вещи, которые не очень ложатся на методы интерфейса, чтобы доп-функциональность работала согласно «верному пути» архитектора.
Абстрактный класс. ну допустим, мы далем абстрактный класс DTO, который выполняет методы to_string и normalize. Наследуюясь от этого абстрактного класса, мы во всех DTO получаем методы to_string и normalize. Плюс защищаемся от того, что кто-то решит нам запороать этот абстрактный класс, либо «решит» что-то сломать в своем DTO
Ну вообще, это все нужно, если ты пишешь хороший проект на Symfony командой. Если это какой-то бложит или небольшой новостник, тебе это все не нужно.
Абстрактные классы в основном используются в том случае, если какую-то часть кода можно описать в родительском классе, но для того чтоб эта часть приобрела смысл, нужна конкретика: дополнить общую картину подробностями в виде методов или полей. Если вы присмотритесь к абстрактным классам в современных фреймворках, то увидите что сам по себе абстрактный класс не имеет смысла. Например, если создать объект такого класса оператором new, то этому объекту всё равно будет чего-то не хватать и именно это что-то и добавляют дочерние классы.
> и в этом случае интерпретатор будет знать как перебрать коллекцию в цикле foreach.
Я бы сказал, что, как раз знать как перебрать он не будет, но сможет, тем не менее, заставить её перебраться. 🙂 Это немного тонкая разница, но тем не менее.
1. Абстрактный класс нельзя создать, только создать обьект от наследуемого класса
2. Абстрактный класс может содержать реализацию, в отличии от интерфейса
3. Абстрактный класс может содержать абстрактные методы, которые необходимо будет реализовать в дочерних классах
4. Можно имплементировать сразу несколько интерфейсов, а наследовать только от одного класса.
5. Трейты очень хорошо комбинируются с интерфейсами
Осознание зачем это нужно, прийдёт к вам в процессе использования)) Почитайте также про SOLID, и попробуйте реализовать эти принципы без абстракций и интерфейсов)
P.S. Домашнее задание
Есть три класса. Квадрат, Прямоугольник, Круг. И класс Ящик. Мы добавляем в ящик, произвольные наборы из фигур, и нужно посчитать площадь всех фигур в ящике.
Ruslan Ruslanov, Зачем указывать квадрату две стороны? Это же квадрат, у него стороны равны
Плюс врывается обезумевший заказчик, и хочет добавить треугольник, а также возможность задавать цвет, но только для круга и квадрата
P.S. Домашнее задание
Есть три класса. Квадрат, Прямоугольник, Круг. И класс Ящик. Мы добавляем в ящик, произвольные наборы из фигур, и нужно посчитать площадь всех фигур в ящике.
))) Я вас удивлю, но условия в жизни меняются чаще чем хотелось бы, и не всегда они меняются на те что ожидалось или хотелось. Для этого люди и придумывают разные практики и методики. Чтоб при очередном таком изменении, минимально переписывать код. А дальше уже каждый ищет для своей задачи эту золотую середину. Я считаю что нужно знать как можно больше подходов, чтоб выбрать оптимальный.
Вот рекомендую это изучить, а как поймете, о чём речь и для чего это всё. Тогда можно уже смело отбрасывать всё и делать как хочется)
https://ota-solid.now.sh/
P.S. В любом случае, это очень часто спрашивают на собеседованиях, так что если ваши планы более грандиозны, чем маленький самописный проект, который вы сами разрабатываете и не меняете в нём ничего, то стоит подготовится
но тогда просто будет сложно работать.
он (абстрактный класс) носит чисто декоративный характер, нужен для ограничения действий разработчика, удобства разработки и вообще это лишь «сахар?.
Абстрактные классы в PHP
В этом уроке, мы обсудим абстрактный класс и его особенности, связанные с объектно-ориентированными методами в PHP. Кроме того, мы изучим реализацию абстрактного класса разобрав несколько примеров.
Что такое абстрактные классы и методы в PHP?
Абстрактные классы — это классы, в которых хотя бы один метод является абстрактным. Методы, объявленные абстрактными, несут, по существу, лишь описательный смысл (имеют только имя и аргументы) и не имеют тела. Таким образом, мы не можем создавать объекты из абстрактных классов. Вместо этого нам нужно создать дочерние классы, которые добавляют код в тела методов и используют эти дочерние классы для создания объектов.
Объявление абстрактных классов
Чтобы объявить абстрактный класс, нам нужно использовать ключевое слово abstract перед именем класса:
Синтаксис
Объявление абстрактных методов
Когда вы добавляете ключевое слово abstract к объявлению метода, он становится абстрактным методом. И помните, абстрактные методы не имеют тела. Поэтому фигурные скобки <> не используются.
Пример
Правила абстракции
Когда дочерний класс наследуется от абстрактного класса, применяются следующие правила:
Видимость абстрактного метода | Видимость дочернего метода |
---|---|
public | public |
protected | protected или public, но не private |
Не абстрактные методы в абстрактном классе
Неабстрактные методы могут быть определены в абстрактном классе. Эти методы будут работать так же, как обычные методы наследования.
Любой класс даже с одним абстрактным методом должен быть объявлен абстрактным. Но абстрактный класс также может иметь неабстрактные методы, к которым дочерние классы могут обращаться и использовать их напрямую, не переопределяя их.
Давайте расширим приведенный выше пример и включим в наш класс неабстрактный метод myMethod2:
Пример
Примечание: В этом основное отличие абстрактных классов от интерфейсов. Абстрактные классы могут иметь реальные методы, а интерфейсы могут иметь только объявления методов.
Пример абстрактного класса в PHP ООП
Родительский абстрактный класс:
Пример
Как создать дочерние классы из абстрактного класса?
Примечание: Дочерние классы, которые наследуются от абстрактных классов, должны добавлять тела к абстрактным методам.
Давайте создадим дочерние классы и определим в них абстрактный метод, унаследованный от родителя, greet():
Пример
Теперь мы можем создавать объекты из дочерних классов:
Пример
Полный код рассмотренного примера абстрактного класса:
Пример
Результат выполнения кода:
Заключение
Абстрактные классы важны, когда вам строго нужны дочерние классы для определения метода. В большинстве случаев абстракция используется, когда родительский класс наследуется несколькими дочерними классами, которые имеют почти одинаковое поведение. Кликните здесь, чтобы попрактиковаться в этой теме. В следующем уроке мы вернемся к концепции абстракции, но на этот раз с использованием интерфейса.
Абстрактные классы в PHP
Для того, чтобы закрепить полученные знания, давайте перепишем задачу из прошлой статьи, но с использованием абстрактного класса. Начнём с класса «Car«, представляющего «абстрактный автомобиль» (файл «car.php«):
Как видите мы поставили ключевое слово «abstract«, означающее, что данный класс является абстрактным. В этом классе мы реализовали конструктор (напоминаю, что создать объект абстрактного класса нельзя). Также описали два абстрактных метода. Под описанием подразумевается определение модификатора доступа, названия функции и входных параметров. А реализовываться эти методы должны в классах-наследниках.
Теперь посмотрите, какой вид имеет класс «Легковой автомобиль«, который, в нашем случае, является уже не абстрактностью, а конкретной моделью (файл «auto.php«):
В данном примере мы реализовали два абстрактных метода, пришедших из класса «Car«, родителя для класса «Auto«.
И, наконец, давайте поиграемся с объектом «Auto«:
Как видите, мы создали объект «Auto«, вывели его свойства, воспользовались методом движения. Ничего сложного тут нет.
Возможно, что Вы скажете: «А что улучшилось-то?». А улучшилось следующее: мы приблизились к реальности, а, следовательно, улучшили понимание структуры программы, упростили её код. Глупо и неразумно создавать некие «абстрактные объекты«, тем самым, плодя ненужные реализации «абстрактных методов«. А наш пример имеет минимум кода, без реализации абстрактности, которая, в общем-то, и не нужна.
Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!
Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.
Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления
Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.
Порекомендуйте эту статью друзьям:
Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):
Комментарии ( 14 ):
Что-то последние три темы вообще не смог понять. В принципе мне понятно про автомобили и про кошек :), что наследуется. Но что мне это даёт при создании сайта, не понятно. Возможно это всё элементарно, но до меня не доходит что-то. И комментариев нет как назло.
Да, применить это при создании сайтов очень сложно, да и вообще как-либо использовать ООП сложно. Это приходит лишь с опытом. Поэтому был записан курс по созданию движка с использованием ООП: http://srs.myrusakovr.ru/php
Спасибо. Может быть когда и пригодится. Но пока, думаю, это для меня рановато.
Я никогда не использовал ООП в создание сайта. Не подскажете когда, где и как использовать ООП на примере, кроме движка?
«А наш пример имеет минимум кода, без реализацию абстрактности, которая, в общем-то, и не нужна.» Здесь опечатка : без реализацию абстрактности.
У вас ошибка в этом предложении «Действительно, этот механизм очень классный, однако, давайте задумайся:»
Я не пойму то-ли код не рабочий то-ли я тупой