php что такое абстрактный класс
Абстрактные классы в ООП на PHP
Для этого существуют так называемые классы. Абстрактные классы представляют собой классы, предназначенные для наследования от них. При этом объекты таких классов нельзя создать.
Для того, чтобы объявить класс абстрактным, нужно при его объявлении написать ключевое слово abstract :
Попытка создать объект класса User вызовет ошибку:
Абстрактные методы
Давайте попробуем на практике. Пусть предполагается, что все потомки класса User должны иметь метод increaseRevenue ( увеличить доход ).
Этот метод должен брать текущий доход пользователя и увеличивать его на некоторую величину, переданную параметром.
Фишка тут в том, что абстрактный метод класса User заставляет программиста реализовывать этот метод в потомках, иначе PHP выдаст ошибку. Таким образом вы, или другой программист, работающий с вашим кодом, никак не сможете забыть реализовать нужный метод в потомке.
Итак, давайте попробуем на практике. Добавим абстрактный метод increaseRevenue в класс User :
Давайте теперь напишем реализацию метода increaseRevenue в классе Employee :
Проверим работу нашего класса:
Некоторые замечания
При наследовании от абстрактного класса, все методы, помеченные абстрактными в родительском классе, должны быть определены в дочернем классе.
Объявления методов также должны совпадать: количество обязательных параметром должно быть одинаковым. Однако класс-потомок может добавлять необязательные параметры, которые не были указаны при объявлении метода в родителе.
Практика
Пусть нам необходимо работать с геометрическими фигурами, например, с квадратами, прямоугольниками, треугольниками и так далее. Пусть каждая фигура будет описываться своим классом, при этом мы хотим сделать так, чтобы каждый класс имел метод для вычисления площади и метод для вычисления периметра фигуры.
Почему класс Figure абстрактный: потому что он не описывает реально существующую геометрическую фигуру и, соответственно, объект этого класса мы не будем создавать.
Почему методы getSquare и getPerimeter абстрактные: потому что каждая фигура имеет свой алгоритм вычисления площади и периметра и, соответственно, класс Figure не может написать реализацию этих методов.
Зачем нам вообще нужен класс Figure : чтобы наследовать от него и таким образом заставить всех наследников реализовать указанные методы.
Итак, напишем реализацию класса Figure :
Пусть теперь мы хотим создать класс Quadrate для описания геометрической фигуры квадрат. Как известно, у квадрата все стороны равны, поэтому для описания квадрата нам нужно задать только его ширину.
Давайте теперь унаследуем наш класс Quadrate от класса Figure :
Сейчас наша реализация класса Quadrate не рабочая, так как мы не написали реализацию абстрактных методов родителя.
Давайте сделаем это:
Давайте создадим квадрат со стороной 2 и найдем его площадь и периметр:
Усложним
Этот метод уже будет не абстрактный, а иметь реализацию, и все потомки смогут воспользоваться этим методом.
Почему мы можем написать реализацию этого метода прямо в классе Figure : потому что этот метод будет одинаковым для всех потомков.
Итак, добавим наш метод:
Применим наш метод:
Абстрактные классы в 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
Спасибо. Может быть когда и пригодится. Но пока, думаю, это для меня рановато.
Я никогда не использовал ООП в создание сайта. Не подскажете когда, где и как использовать ООП на примере, кроме движка?
«А наш пример имеет минимум кода, без реализацию абстрактности, которая, в общем-то, и не нужна.» Здесь опечатка : без реализацию абстрактности.
У вас ошибка в этом предложении «Действительно, этот механизм очень классный, однако, давайте задумайся:»
Я не пойму то-ли код не рабочий то-ли я тупой
Абстрактные классы в PHP
В этом уроке, мы обсудим абстрактный класс и его особенности, связанные с объектно-ориентированными методами в PHP. Кроме того, мы изучим реализацию абстрактного класса разобрав несколько примеров.
Что такое абстрактные классы и методы в PHP?
Абстрактные классы — это классы, в которых хотя бы один метод является абстрактным. Методы, объявленные абстрактными, несут, по существу, лишь описательный смысл (имеют только имя и аргументы) и не имеют тела. Таким образом, мы не можем создавать объекты из абстрактных классов. Вместо этого нам нужно создать дочерние классы, которые добавляют код в тела методов и используют эти дочерние классы для создания объектов.
Объявление абстрактных классов
Чтобы объявить абстрактный класс, нам нужно использовать ключевое слово abstract перед именем класса:
Синтаксис
Объявление абстрактных методов
Когда вы добавляете ключевое слово abstract к объявлению метода, он становится абстрактным методом. И помните, абстрактные методы не имеют тела. Поэтому фигурные скобки <> не используются.
Пример
Правила абстракции
Когда дочерний класс наследуется от абстрактного класса, применяются следующие правила:
Видимость абстрактного метода | Видимость дочернего метода |
---|---|
public | public |
protected | protected или public, но не private |
Не абстрактные методы в абстрактном классе
Неабстрактные методы могут быть определены в абстрактном классе. Эти методы будут работать так же, как обычные методы наследования.
Любой класс даже с одним абстрактным методом должен быть объявлен абстрактным. Но абстрактный класс также может иметь неабстрактные методы, к которым дочерние классы могут обращаться и использовать их напрямую, не переопределяя их.
Давайте расширим приведенный выше пример и включим в наш класс неабстрактный метод myMethod2:
Пример
Примечание: В этом основное отличие абстрактных классов от интерфейсов. Абстрактные классы могут иметь реальные методы, а интерфейсы могут иметь только объявления методов.
Пример абстрактного класса в PHP ООП
Родительский абстрактный класс:
Пример
Как создать дочерние классы из абстрактного класса?
Примечание: Дочерние классы, которые наследуются от абстрактных классов, должны добавлять тела к абстрактным методам.
Давайте создадим дочерние классы и определим в них абстрактный метод, унаследованный от родителя, greet():
Пример
Теперь мы можем создавать объекты из дочерних классов:
Пример
Полный код рассмотренного примера абстрактного класса:
Пример
Результат выполнения кода:
Заключение
Абстрактные классы важны, когда вам строго нужны дочерние классы для определения метода. В большинстве случаев абстракция используется, когда родительский класс наследуется несколькими дочерними классами, которые имеют почти одинаковое поведение. Кликните здесь, чтобы попрактиковаться в этой теме. В следующем уроке мы вернемся к концепции абстракции, но на этот раз с использованием интерфейса.
Абстрактные классы
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 что такое абстрактный класс
Reg.ru: домены и хостинг
Крупнейший регистратор и хостинг-провайдер в России.
Более 2 миллионов доменных имен на обслуживании.
Продвижение, почта для домена, решения для бизнеса.
Более 700 тыс. клиентов по всему миру уже сделали свой выбор.
Бесплатный Курс «Практика HTML5 и CSS3»
Освойте бесплатно пошаговый видеокурс
по основам адаптивной верстки
на HTML5 и CSS3 с полного нуля.
Фреймворк Bootstrap: быстрая адаптивная вёрстка
Пошаговый видеокурс по основам адаптивной верстки в фреймворке Bootstrap.
Научитесь верстать просто, быстро и качественно, используя мощный и практичный инструмент.
Верстайте на заказ и получайте деньги.
Что нужно знать для создания PHP-сайтов?
Ответ здесь. Только самое важное и полезное для начинающего веб-разработчика.
Узнайте, как создавать качественные сайты на PHP всего за 2 часа и 27 минут!
Создайте свой сайт за 3 часа и 30 минут.
После просмотра данного видеокурса у Вас на компьютере будет готовый к использованию сайт, который Вы сделали сами.
Вам останется лишь наполнить его нужной информацией и изменить дизайн (по желанию).
Изучите основы HTML и CSS менее чем за 4 часа.
После просмотра данного видеокурса Вы перестанете с ужасом смотреть на HTML-код и будете понимать, как он работает.
Вы сможете создать свои первые HTML-страницы и придать им нужный вид с помощью CSS.
Бесплатный курс «Сайт на WordPress»
Хотите освоить CMS WordPress?
Получите уроки по дизайну и верстке сайта на WordPress.
Научитесь работать с темами и нарезать макет.
Бесплатный видеокурс по рисованию дизайна сайта, его верстке и установке на CMS WordPress!
Хотите изучить JavaScript, но не знаете, как подступиться?
После прохождения видеокурса Вы освоите базовые моменты работы с JavaScript.
Развеются мифы о сложности работы с этим языком, и Вы будете готовы изучать JavaScript на более серьезном уровне.
*Наведите курсор мыши для приостановки прокрутки.
Абстрактные классы и интерфейсы в PHP
Абстрактные классы в PHP
Появление абстрактных классов в свое время стало одним из главных нововведений в PHP 5. Это было еще одним подтверждением растущей приверженности PHP объектно-ориентированному проектированию.
Нельзя создать экземпляр абстрактного класса. Вместо этого в нем определяется (и, возможно, частично реализуется) интерфейс для любого класса, который может его расширить.
Абстрактный класс определяется с помощью ключевого слова abstract. Давайте переопределим класс ShopProductWriter, который мы создали в одном из предыдущих материалов, в виде абстрактного класса.
В абстрактном классе вы можете создавать методы и свойства как обычно, но любая попытка создать его экземпляр приведет к ошибке.
В большинстве случаев абстрактный класс будет содержать, по меньшей мере, один абстрактный метод. Как и класс, он описывается с помощью ключевого слова abstract.
Абстрактный метод не может иметь реализацию в абстрактном классе. Он объявляется как обычный метод, но объявление заканчивается точкой с запятой, а не телом метода. Давайте добавим абстрактный метод write() к классу ShopProductWriter.
Создавая абстрактный метод, вы гарантируете, что его реализация будет доступной во всех конкретных дочерних классах, но детали этой реализации остаются неопределенными.
Если бы мы, как показано ниже, создали класс, производный от ShopProductWriter, в котором метод write() не был бы реализован
то столкнулись бы со следующей ошибкой.
В переводе на русский это звучит так:
Итак, в любом классе, который расширяет абстрактный класс, должны быть реализованы все абстрактные методы, либо сам класс должен быть объявлен абстрактным. При этом в расширяющем классе должны быть не просто реализованы все абстрактные методы, но и должна быть воспроизведена сигнатура их методов.
Это означает, что уровень доступа в реализующем методе не может быть более строгим, чем в абстрактном методе.
Реализующему методу также должно передаваться такое же количество аргументов, как и абстрактному методу, а также в нем должны воспроизводсться все уточнения типов класса.
Ниже приведены две реализации класса ShopProductWriter.
Теперь методу, которому требуется передать объект типа ShopProductWriter, не нужно точно знать, какой из этих двух классов он получает, поскольку ему достоверно известно, что в обоих классах реализован метод write().
Обратите внимание на то, что мы не проверяем тип переменной $products, прежде чем использовать ее как массив. Причина в том, что это свойство инициализируется как пустой массив в классе ShopProductWriter.
Интерфейс может только определять функциональность, но никогда не реализует ее.
Для объявления интерфейса используется ключевое слово interface. Интерфейс может содержать объявления свойств и методов, но не тела этих методов.
Давайте определим интерфейс.
Как видите, интерфейс очень похож на класс. Любой класс, содержищий этот интерфейс, должен реализовывать все методы, определенные в интерфейсе; в противном случае класс должен быть объявлен как абстрактный.
При реализации интерфейса в классе, имя интерфейса указывается в объявлении этого класса после ключевого слова implements.
После этого процесс реализации интерфейса станет точно таким же, как расширение абстрактного класса, который содержит только абстрактные методы. Давайте сделаем так, чтобы в классе ShopProduct был реализован интерфейс Chargeable.
В классе ShopProduct уже есть метод getPrice(), что же может быть полезного в реализации интерфейса Chargeable?
И снова ответ связан с типами. Дело в том, что реализующий класс принимает тип класса и интерфейса, который он расширяет. Это означает, что класс CDProduct относится к следующим типам:
— CDProduct
— ShopProduct
— Chargeable
Эту особенность можно использовать в клиентском коде. Как известно, тип объекта определяет его функциональные возможности. Поэтому метод
«знает», что у объекта $prod есть метод getPlayLength() в дополнение ко всем методам, определенным в классе ShopProduct и интерфейсе Chargeable.
Если тот же самый объект CDProduct передается методу
то известно, что объект $prod поддерживает все методы, определенные в классе ShopProduct. Однако без дальнейшей проверки данный метод ничего не будет знать о методе getPlayLength().
И снова, если передать тот же объект CDProduct методу
данному методу ничего не будет известно обо всех методах, определенных в классах ShopProduct или CDProduct. При этом интерпретатор только проверит, содержит ли аргумент $item метод getPrice().
Поскольку интерфейс можно реализовать в любом классе (на самом деле, в классе можно реализовать любое количество интерфейсов), с помощью интерфейсов можно эффективно объединить типы данных, не связанных никакими другими отношениями. В результате мы можем определить совершенно новый класс, который реализует интерфейс Chargeable.
Затем объект типа Shipping мы можем передать методу addChargeableItem(), точно так же, как мы передавали ему объект типа shopProduct.
В классе можно как расширить суперкласс, так и реализовать любое количество интерфейсов. При этом ключевое слово extends должно предшествовать ключевому слову implements.
Обратите внимание на то, что в классе Concultancy реализуется более одного интерфейса. После ключевого слова implements можно перечислить через запятую несколько интерфейсов.
При этом важно помнить, что в PHP поддерживается наследование только от одного родителя (так называемое одиночное наследование), поэтому после ключевого слова extends можно указать только одно имя базового класса.
На этом здесь остановимся, а в следующей статье продолжим разговор уже о позднем статическом связывании в PHP и ключевом слове static.
Понравился материал и хотите отблагодарить?
Просто поделитесь с друзьями и коллегами!