Абстрактные классы в PHP


Оглавление (нажмите, чтобы открыть):

Абстрактные классы

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

При наследовании от абстрактного класса, все методы, помеченные абстрактными в родительском классе, должны быть определены в классе-потомке; кроме того, область видимости этих методов должна совпадать (или быть менее строгой). Более того, контроль типов (будет рассмотрено) и количество обязательных аргументов должно быть одинаковым.

Пример абстрактного класса:

Ключевое слово «static»

Объявление свойств и методов класса статическими (static) позволяет обращаться к ним без создания экземпляра класса. Атрибут класса, объявленный статическим, не может быть доступен посредством экземпляра класса (но статический метод может быть вызван).

Доступ к статическим свойствам класса может быть получен через оператор ::

Начиная с версии PHP 5.3.0 существует возможность ссылаться на класс используя переменную. Поэтому значение переменной в таком случае не может быть ключевым словом (например, self, parent и static).

абстракция — Почему абстрактные классы необходимы в PHP?

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

Решение

Я думаю, что важно, во-первых, уточнить терминологию, чтобы более детально ответить на этот вопрос.

  1. наследование
    • Наследование на самом деле широко применяется ко многим принципам и концепциям объектно-ориентированного программирования. Это просто влечет за собой одно, выведенное из другого. Итак, реализуете ли вы интерфейс или расширяете класс, вы все еще используете форму наследования. Они не являются взаимоисключающими понятиями.
  2. интерфейс
    • Попробуйте думать об интерфейсе, как если бы вы были контрактом. Сам контракт — это просто документ, обычно между двумя или более сторонами, в котором изложены правила их отношений. Интерфейсы, особенно в контексте ООП и PHP, не обеспечивают реализацию. Они предоставляют только необходимые публичные методы, которые реализующий класс ДОЛЖЕН воплощать в жизнь. Интерфейсы также не могут быть созданы сами по себе.
  3. абстрактный класс
    • Абстрактный класс похож на интерфейс в том, что он не может быть реализован сам по себе, но не обязательно обеспечивает выполнение контракта для расширяющегося класса. Поскольку это фактический класс, а не просто интерфейс, он также допускает реализацию. Эта реализация может быть предоставлена ​​самим абстрактным классом или оставлена ​​до расширяющего класса, если метод объявлен как abstract в абстрактном классе. Это также позволяет реализовать свойства и частные / защищенные методы, потому что наследование здесь действует как базовый класс, а не просто как требование.

Чтобы ответить на вопрос «почему у нас есть абстрактные классы в PHP«, потому что это полезно. Сначала вы можете рассматривать их как неразрешимые идеи, но на самом деле они могут работать вместе, обеспечивая совместную полезность.

пример

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

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

Дальнейший пример

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

Посмотрите на Device Сам интерфейс, как хороший пример. Мы полагаемся на input способ принять Stream тип и output способ вернуть Stream тип. поскольку Stream сам по себе может быть интерфейсом, это означает, что любой тип, реализующий Stream приемлемо Так что я мог создать свой собственный класс и реализовать Stream интерфейс, не нарушая этот код.

Другие решения

abstract Класс используется для предоставления набора членов-данных или методов, которые должны быть доступны для классов, которые наследуются от него, даже если базовый класс не особенно полезен (и никогда не должен создаваться самостоятельно) без унаследованной реализации.

отсюда наследование вступает во владение.

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


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

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

Пара производных классов:

Можем ли мы предоставить реализацию метода draw() в базовом классе Shape ?

Конечно, нет. Shape является общим, это не означает только «круг» или «прямоугольник» или «треугольник». Нет способа обеспечить разумную реализацию для Shape::draw() потому что мы даже не знаем, какую форму он представляет.

Можно ли предоставить пустую реализацию для Shape::draw() ?

Видимо это так. Однако, если подумать, ясно, что это небезопасно. Объекты класса, который расширяется Shape и не обеспечивает собственную реализацию метода draw() не может быть нарисовано.

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

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

Класс, который имеет abstract метод не полностью определен. Это причина, почему это abstract класс, и он не может быть создан.

Абстрактный класс php

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

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

На первом этапе программирования, новички не понимают смысла и назначения объектно-ориентированного подхода. Смысл понять можно только разрабатывая сложные проекты.

Перед разработкой структуры проекта, не плохо бы представлять, что такое абстрактный класс.

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

Как создать абстрактный php класс

Чтобы сделать класс абстрактным, нужно перед объявлением класса поставить идентификатор: abstract .

Для качественного усвоения материала предлагаю рассмотреть, всю цепочку взаимодействия классов, на примере упрощенного абстрактного класса Monster, характерного большинству из сегодняшних видео игр:

abstract class Monster <
public $size ; // размер
public $weight ; // вес
public $aggressive ; // статус (аресивный, добрый)

abstract public function demeanor ( $action ) ; //поведение

public function initialization ( $arr ) < //инициализация

$this -> size = $arr [ ‘size’ ] ;
$this -> weight = $arr [ ‘weight’ ] ;
$this -> aggressive = $arr [ ‘aggressive’ ] ;
>

public function print_data ( ) < // вывод данных
echo «
» ;
print_r ( $this ) ;
>
>

Задача класса состоит в реализации базовых свойств любого монстра в RPG игре.


К базовым свойствам присущим любой особи можно отнести: размер, вес, статус, местоположение и т.д.

Свойства монстра будут инициализироваться в стандартной базовой функции initialization($arr);

Обратите внимание, в классе присутствует абстрактный метод demeanor() , необходимый для задания индивидуального поведения каждого из объектов.

Мастер Йода рекомендует:  Баг в таблице

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

Как использовать абстрактный класс PHP

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

Данный класс наследует все методы и свойства базового класса Monster , а также определяет новое поведение для объекта это класса.

Т.е. другими словами, дописывается логика абстрактного метода. В данном случаем в примере реализуется смена статуса монстра, при получении события равного единице. Если обработчик поведения подучает событие = 1 то монстр становится агресивным.

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

Для этого мы создаем новый класс Monster_Alien , в котором прописываем новое поведение для метода demeanor() .

// Класс описывающий второго монстра
class Monster_Alien extends Monster <
public function __construct ( $arr ) <
$this -> initialization ( $arr ) ;
>

public function demeanor ( $action ) <
if ( $action == 1 ) <
echo «
Злобный звук, призывающий к бою.» ;
>
return $action ;
>
>

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

Абстрактный php класс и классы потомки определенны, давайте проверим их работоспособность.

Создадим объект класса Monster_Zombie , передав его конструктору необходимые данные.

Воспользуемся базовым методом вывода данных об объекте:

Заставим нашего доброго зомби разозлиться, и передадим событие равное единице в метод обрабатывающий поведение зомби:

Проверим повлияли ли наши действия на зомби… ��

Все верно, свойство aggressive приняло значение yes и теперь данный объект является агрессивным.

Создадим монстра типа Monster_Alien :

Проделаем с ним тоже, что и с Zombie:

В результате увидим такую картину:

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

Подведем итоги и закрепим несколько важных особенностей абстрактного класса.

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


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

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

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

Что же такое интерфейсы, и для чего они нужны?

Интерфейсы объявляются при помощи идентификатора interface перед объявлением класса.

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

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

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

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

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

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

Абстрактные классы в PHP

Освойте бесплатно наиболее простой, быстрый и гибкий способ создавать адаптивные веб-сайты.

Дизайн лендинга

Создавайте дизайн любых сайтов — для себя и на заказ!

Популярное

  • Главная
  • ->
  • Материалы
  • ->
  • Абстрактные классы и интерфейсы в 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

Появление абстрактных классов в свое время стало одним из главных нововведений в PHP 5. Это было еще одним подтверждением растущей приверженности PHP объектно-ориентированному проектированию.

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

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

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

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

Абстрактный метод не может иметь реализацию в абстрактном классе. Он объявляется как обычный метод, но объявление заканчивается точкой с запятой, а не телом метода. Давайте добавим абстрактный метод write() к классу ShopProductWriter.

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

Если бы мы, как показано ниже, создали класс, производный от ShopProductWriter, в котором метод write() не был бы реализован

то столкнулись бы со следующей ошибкой.

В переводе на русский это звучит так:

Класс ErrorWriter содержит один абстрактный метод и поэтому должен быть объявлен как абстрактный или реализовать перечисленные методы .

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

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

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

Ниже приведены две реализации класса ShopProductWriter.

Мы создали два класса, каждый с собственной реализацией метода write(). Первый выводит данные о товаре в формате XML, а второй — в текстовом виде.

Теперь методу, которому требуется передать объект типа ShopProductWriter, не нужно точно знать, какой из этих двух классов он получает, поскольку ему достоверно известно, что в обоих классах реализован метод write().


Обратите внимание на то, что мы не проверяем тип переменной $products, прежде чем использовать ее как массив. Причина в том, что это свойство инициализируется как пустой массив в классе ShopProductWriter.

Мастер Йода рекомендует:  Взаимодействие нескольких форм

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

Как известно, в абстрактном классе допускается частичная реализация методов, не объявленных абстрактными. В отличие от них, интерфейсы — это чистой воды шаблоны.

Интерфейс может только определять функциональность, но никогда не реализует ее.

Для объявления интерфейса используется ключевое слово 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.

Для клиента, работающего с объектом типа Chargeable, очень важно то, что он может вызвать метод getPrice(). Любые другие имеющиеся методы связаны с другими типами — через собственный класс объекта, суперкласс или другой интерфейс. Но они не имеют никакого отношения к нашему клиенту.

В классе можно как расширить суперкласс, так и реализовать любое количество интерфейсов. При этом ключевое слово extends должно предшествовать ключевому слову implements.

Обратите внимание на то, что в классе Concultancy реализуется более одного интерфейса. После ключевого слова implements можно перечислить через запятую несколько интерфейсов.

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

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


Понравился материал и хотите отблагодарить?
Просто поделитесь с друзьями и коллегами!

Все о WEB программировании

WEB программирование от А до Я

Заказать сайт:

Социальные сети:

Партнеры:

Понимание использования интерфейса и абстрактного класса в PHP

Доброго времени суток. В интернете нашел интересную статью о понимании использования интерфейсов и абстрактных классов в PHP. Разницу между ними. И решил сделать перевод (но немножко дополненный), т.к. статья наглядно показывает нам, как и когда использовать интерфейсы и абстрактные классы. И так, поехали…

Интерфейс

Давайте обратимся к официальной документации PHP и посмотрим определение интерфейса:

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

Интерфейс в PHP определяется, как и класс за исключением вместо ключевого слова class мы указываем interface.

Все методы интерфейса являются абстрактными и открытыми – это природа интерфейса. Пример объявления интерфейса:

В интерфейсе тело метода не определено, мы определяем только имя и параметры. Теперь давайте рассмотрим, когда использовать интерфейс. Например, у нас есть следующий код:

В приведенном выше примере автор не использует интерфейс. Автор пишет в журнал, используя класс LogToFile. Но если мы захотим писать данные в журнал с использованием класса LogToDatabase. Необходимо изменить жестко закодированную ссылку на класс:

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

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

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

Абстрактный класс

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

PHP 5 поддерживает определение абстрактных классов и методов. Объекты классов, определенных как абстрактные, не могут быть созданы, и любой класс, который содержит по крайней мере один абстрактный метод, должен быть определен как абстрактный. Методы, объявленные абстрактными, несут, по существу, лишь описательный смысл и не могут включать реализацию.

Когда использовать абстрактный класс?

Например, давайте рассмотрим класс Tea

Теперь рассмотрим класс Coffee:

В приведенных выше классах три метода addHotWater(), addSugar(), addMilk() одинаковы. Поэтому мы должны удалить дублированный код:


Автор создает абстрактный класс и называет его Template. В этом классе определяет три метода addHotWater (), addSugar () и addMilk () и создает абстрактный метод с именем addPrimaryToppings.

Теперь, если создавать класс Tea его необходимо делать расширенным для класса Template, тогда мы получаем три определенных метода и должны определить метод addPrimaryToppings ().

Для чего нужны абстрактные классы и интерфейсы PHP?

Пример из жизни если можно =)

Вроде писать классы можно и без них

Где их можно применить?

Вот нашел развернутый ответ

ссылка на ответ

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

6 ответов 6

Можно, конечно, и без абстрактных классов. Но с ними все же удобнее. Например в следующем случае: вам надо реализовать иерархию классов, где есть один базовый класс и несколько производных. При этом нужно реализовать некий метод, который должен быть у всех классов, но во всех он должен быть реализован по-своему. Реализовать этот метод в базовом не абстрактном классе вы не можете — в таком случае он будет общим для всех производных. Можно, конечно, сделать его виртуальным в базовом классе и переопределять в производных, но тогда напрашивается вопрос: зачем этот метод реализовывать в базовом классе, если нужны только его реализации, зависящие от конкретного производного класса. Это иллюстрируется хрестоматийным примером про геометрические фигуры, когда у вас есть базовый класс Figure и производные от него Circle, Square, каждый из которых должен иметь метод для отрисовки (скажем, Draw()). Тут можно увидеть, что во-первых, Draw() должен быть разным для каждого из производных классов, а во-вторых, его не очень-то и нужно реализовывать в базовом, так как непонятно, как должна выглядеть «просто фигура». При этом у класса Figure может быть какой-то набор базовых методов, реализация которых может быть общей для всех производных. То есть вполне разумно сделать базовый класс именно абстрактным (а не интерфейсом или обычным, не абстрактным классом)

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

Мастер Йода рекомендует:  Python и R что выбрать для Data Science в 2020

Представьте, что вам нужно описать модель работы бензозаправки. Для ее отработки вам безусловно понадобится экземпляр автомобиля. Но в данный момент вы не хотите задумываться о конкретной реализации этого класса — его методы могут возвращать mock значения. К тому же вам наверняка могут понадобится свойства в этом классе и соответственно рабочие геттеры и сеттеры. К тому же, стоит проконтроллировать, что соседние разработчики не будут дописывать к этому классу какую-то конкретную логику, чтобы потом использовать ее в своем коде и таким образом связать ваш код лишними зависимостями. Для этих целей идеально подойдет именно абстрактный класс, созданием которого вы говорите: «это класс с очень общей логикой и возможностью хранить данные в свойствах. В последствии мы сделаем для него конкретных потомков, но сейчас не до этого. Пожалуйста, не дописывайте сюда методов с конкретной логикой.»

Уроки PHP – Абстрактные классы и ключевые слова

В предыдущем уроке мы рассмотрели конструкторы и деструкторы в PHP. Следующим пунктом идет рассмотрение абстрактных классов и ключевых слов static и final .

В чем разница между обычными классами и абстрактными? Разница между «обычным» и абстрактным классом заключается в том, что абстрактный класс может быть унаследован, но нельзя создать его экземпляр (не может быть инстанцирован). Он также может содержать абстрактные методы. Это методы без какого-либо реального кода в них. В таких классах вы используете только ключевое слово abstract , название метода и параметры.

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

Особенности абстрактных классов

Необходимо запомнить две важные вещи, связанные с методами, объявленными внутри абстрактного класса. Во-первых, когда класс наследуется от абстрактного класса, он должен реализовать все его абстрактные методы. Во-вторых, абстрактные методы могут использоваться только в абстрактных классах.

Ключевое слово static

Следующая вещь, которая довольно часто встречается в PHP-классах, это два ключевых слова static и final . Первое ключевое слово ( static ) определяет свойства и методы класса, к которым можно получить доступ, не создавая новый объект или экземпляр этого класса. Как получить доступ к любому статическому свойству или методу? Вы должны использовать оператор :: (двойное двоеточие). Это то, что называется оператором разрешения области видимости. Вы вставляете его между именем класса и именем свойства или метода.

Если вам нужно получить доступ к статическому свойству из статического метода, вам нужно использовать другое ключевое слово self .

Ключевое слово final

Второе ключевое слово – final . Это ключевое слово определяет методы, которые нельзя переопределить в дочерних классах. Вы также можете использовать это ключевое слово при объявлении новых классов. Классы, которые вы объявили с помощью ключевого слова final , не могут быть унаследованы. Давайте рассмотрим простой пример того, как изменить final метод и унаследовать final класс.

На сегодня все! В последующих статьях мы будем рассматривать более углубленные вещи языка программирования PHP.


Классы в объектно-ориентированном программировании на PHP

Дата публикации: 2020-01-03

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

Напомню, что класс ООП на PHP – это чертеж, или шаблон для формирования будущего объекта, в котором описаны постоянные или переменные хранящиеся данные, а также действия, то есть функции, именуемые методами, которые он может выполнять. Мы с Вами об этом уже говорили, и Вы знаете, как создаются простые классы. Помимо этого я кратко вспоминал, что существуют так называемые абстрактные классы в ООП PHP. А значит, давайте более подробно их изучим.

Абстрактным классом в объектно-ориентированном программировании на PHP является класс, для которого, невозможно создать объект. Они были введены в язык PHP , начиная с версии 5 и, конечно же, сразу возникает вопрос – для чего нужен класс подобного рода? Ответ достаточно прост — абстрактные классы, как правило, создаются в качестве родительских, то есть в создаваемых проектах они наследуются другими классами и, по сути, определяют интерфейс доступа к классам, которые будут их расширять.

Для создания абстрактного класса необходимо прописывать специальное слово abstract.

Как создать сайт самому?

Какие технологии и знания необходимы сегодня, чтобы создавать сайты самостоятельно? Узнайте на интенсиве!

Интерфейсы и абстрактные классы в PHP

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

Ключевое отличия:

  • интерфейс не может реализовывать логику приложения, он только описывает структуру класса
  • интерфейсов можно реализовывать столько, сколько нужно; класс может наследоваться только от одного класса
  • абстрактный класс невозможно инициализировать
  • абстрактный класс может содержать реализацию методов

Что такое абстрактный класс в PHP?

Что такое абстрактный класс в PHP?

Как это можно использовать?

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

Целью этого является предоставление типа шаблона для наследования и принудительного наследования класса для реализации абстрактных методов.

Таким образом, абстрактный класс — это нечто среднее между обычным классом и чистым интерфейсом. Также интерфейсы являются особым случаем абстрактных классов, где ВСЕ методы абстрактны.

Подробнее см. в этом разделе руководства по PHP.

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

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

2. Любой класс, содержащий хотя бы один абстрактный метод, также должен быть абстрактным: абстрактный класс может иметь абстрактные и не абстрактные методы, но должен содержать хотя бы один абстрактный метод. Если класс имеет хотя бы один абстрактный метод, класс должен быть объявлен абстрактным.

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

3. Абстрактный метод не может содержать тело. Методы, определенные как абстрактные, просто объявляют подпись метода — они не могут определить реализацию. Но не абстрактный метод может определить реализацию.

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

5. То же (или менее ограниченное) видимость. При наследовании от абстрактного класса все методы, помеченные как абстрактные в объявлении родительского класса, должны определяться дочерним элементом; кроме того, эти методы должны быть определены с той же (или менее ограниченной) видимостью. Например, если абстрактный метод определяется как защищенный, реализация функции должна быть определена как защищенная или общедоступная, но не закрытая.

Обратите внимание, что абстрактный метод не должен быть закрытым.

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

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

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

ниже пример вызовет Неустранимая ошибка: класс «лошадь» не найден

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