что такое полиморфизм в php
Полиморфизм в PHP
В этом уроке мы поговорим о последнем из трёх китов ООП – полиморфизме. В этом уроке нам придется отойти от примеров с котиками и собачками, и немного удариться в абстракции.
Однако перед этим давайте вспомним конструкцию instanceof. Она позволяет узнать, является ли объект экземпляром какого-то класса, либо что он реализует какой-либо интерфейс. Возвращает true или false.
Давайте создадим ещё один класс, который будет наследником класса A, и выполним ту же проверку для объекта этого класса.
При этом если проверить объект дочернего класса, является ли он объектом родительского класса, то мы получим true.
Это правило работает только в одну сторону, объекты родительского класса не будут являться экземплярами дочернего.
Согласитесь, это вполне логично.
Таким образом объекты дочерних классов будут проходить проверку на то, что они являются экземплярами родительских классов.
Как мы помним, методы объектов родительских классов у нас доступны и в дочерних – они наследуются. Соответственно мы можем быть уверены, что эти же методы есть и у дочерних объектов. Конкретно в нашем примере – у объектов класса B будет метод sayHello(), унаследованный от A.
Или в примере с интерфейсами из прошлого урока – мы определили, что объекты, реализовавшие какой-то интерфейс обязательно будут иметь метод с определённым набором параметров. То есть мы можем рассчитывать на то, что этот метод у объекта гарантированно есть и мы можем его вызвать.
Благодаря этому свойству объектов мы можем ожидать от них какого-то определенного поведения, если они являются объектами какого-то класса или реализуют какой-то интерфейс.
Это свойство, благодаря которому мы можем зависеть не от конкретной реализации (проще говоря конкретного класса), а от абстракции (интерфейса), и есть – полиморфизм.
Да-да, в примере про вычисление площадей фигур мы уже сталкивались с полиморфизмом! В тот момент, когда мы проверяли, имеется ли у объекта интерфейс для вычисления площади, мы работали с проявлением полиморфизма.
Переопределение методов
Как мы уже сказали, в дочерних объектах доступны методы объектов родительского класса.
Однако, мы можем переопределить этот метод в классе B. Для этого мы описываем метод с таким же названием и описываем в нём свою логику:
Мы также можем вызвать родительский метод в дочернем при помощи слова parent и двойного двоеточия.
Мы вызвали родительский метод, и дополнили его функционал. Так часто приходится делать в реальных проектах. Буквально через пару уроков вы столкнетесь с более понятными примерами того, для чего всё это нужно. Но пока что мы должны изучить базу на немного искусственных примерах. К сожалению, придумать что-то более интересное я не смог.
И ещё один примерчик, тоже искуственный.
Как думаете, что выведет этот код?
На этом с полиморфизмом пока всё, если что-то непонятно – пишите в комментах.
Понимание и применение полиморфизма в PHP
В объектно-ориентированном программировании полиморфизм является мощным и фундаментальным инструментом. Его можно использовать для создания более органичного потока в вашем приложении. Этот урок опишет общую концепцию полиморфизма и как его можно легко развернуть в PHP.
Что такое полиморфизм?
Полиморфизм — это длинное слово для очень простого понятия.
Полиморфизм описывает шаблон в объектно-ориентированном программировании, в котором классы имеют различную функциональность, совместно используя общий интерфейс.
Прелесть полиморфизма в том, что коду, работающему с разными классами, не нужно знать, какой класс он использует, поскольку все они используются одинаково.
Реальная аналогия полиморфизма — это кнопка. Все знают, как использовать кнопку: вы просто нажимаете на нее. Однако то, что кнопка «делает», зависит от того, с чем она связана, и от контекста, в котором она используется, но результат не влияет на то, как она используется. Если ваш босс говорит вам нажать кнопку, у вас уже есть вся информация, необходимая для выполнения задачи.
В мире программирования полиморфизм используется, чтобы сделать приложения более модульными и расширяемыми. Вместо беспорядочных условных выражений, описывающих различные варианты действий, вы создаете взаимозаменяемые объекты, которые выбираете в зависимости от ваших потребностей. Это основная цель полиморфизма.
Интерфейсы
Интерфейс
Интерфейс похож на класс за исключением того, что он не может содержать код. Интерфейс может определять имена методов и аргументы, но не содержимое методов. Любые классы, реализующие интерфейс, должны реализовывать все методы, определенные интерфейсом. Класс может реализовывать несколько интерфейсов.
Интерфейс объявляется с использованием ключевого слова interface :
Полиморфизм в ООП на PHP
В этом уроке мы узнаем о « полиморфизме» (греч. «Множество форм») — соглашении об именах, которое может помочь нам написать код, который будет намного более последовательным и простым в использовании. Согласно принципу полиморфизма, методы в разных классах, которые делают похожие вещи, должны иметь одно и то же имя.
Что такое полиформизм?
Полиморфизм — это, по сути, шаблон ООП, который позволяет множеству классов с разными функциями выполнять или совместно использовать общий интерфейс.
В мире программирования полиморфизм используется для того, чтобы сделать приложения более модульными и расширяемыми. Вместо беспорядочных условных утверждений, описывающих различные варианты действий, вы создаете взаимозаменяемые объекты, которые выбираете в зависимости от ваших потребностей. Это основная цель полиморфизма.
Ярким примером являются классы, которые представляют геометрические фигуры (такие как прямоугольники, круги и восьмиугольники), которые отличаются друг от друга количеством ребер и формулой, которая вычисляет их площадь, но все они имеют свою площадь, которая может быть рассчитывается своим методом. Принцип полиморфизма гласит, что в этом случае все методы, вычисляющие площадь (и неважно, для какой формы или класса) будут иметь одно и то же имя.
Как реализовать принцип полиморфизма?
Чтобы реализовать принцип полиморфизма, мы можем выбирать между абстрактными классами и интерфейсами.
В приведенном ниже примере интерфейс с именем Shape фиксирует все классы, реализующие его, для определения абстрактного метода с именем calcArea() :
Пример
Соответственно, класс Circle реализует интерфейс, помещая в метод calcArea() формулу, вычисляющую площадь кругов:
Пример
с формулой вычисления, которая подходит для прямоугольников:
Пример
Теперь мы можем создавать объекты из конкретных классов:
Пример
Теперь мы можем использовать методы calcArea() для вычисления площади фигур:
Пример
Результат выполнения кода:
Вывод
В этом уроке мы узнали, как реализовать принцип полиморфизма в PHP. Кликните здесь, чтобы попрактиковаться в предмете.
Что такое полиморфизм на самом деле. В PHP он тоже существует.
Написать этот пост побудила недавняя статья о полиморфизме. Она вызвала много споров, но знающие люди понимают, что автор написал скорее о наследовании и о переопределении методов, чем о полиморфизме. Не буду говорить ни хорошее ни плохое о той статье, а просто расскажу, что такое полиморфизм на самом деле. Дабы начинающие php-программисты не остались в заблуждении.
Самое простое — это охарактеризовать парадигму полиморфизма как взаимозаменяемость объектов с одинаковым интерфейсом, в чем можно убедиться в википедии.
Итак, на чем основан полиморфизм.
Мы имеем класс или интерфейс (далее интерфейс), который будет являться каркасом, надстройкой и пр. Этот интерфейс будет определять общее поведение всех своих наследников, т.е. как будут называться их основные действия (методы). Ну а наследники, в свою очередь, могут переопределять эти методы, т.е. задавать индивидуальное поведение данных методов. Эта часть была представлена в статье
s_a_p’а. Но это только основа полиморфизма. Сама же его суть заключается в том, что мы гарантируем себе, что все методы интерфейса будут вести себя «правильно» независимо от того, какой конкретно производный класс используется. Возможно сейчас это не совсем понятно, но ниже я приведу пример, где ситуация прояснится.
Я не буду углубляться непосредственно в сам полиморфизм и не стану писать о полиморфизме времени и компиляции. Будем ближе к теме данного блога, а именно к PHP.
Полиморфизм в PHP
Язык PHP поддерживает полиморфизм в том смысле, что позволяет использовать вместо экземпляров родительского класса экземпляры подкласса. Ввод в действие требуемого метода осуществляется на этапе прогона. Поддержка перегрузки методов, при которой ввод метода в действие осуществляется с учетом сигнатуры метода, отсутствует. Дело в том, что в каждом классе может присутствовать только один метод с определенным именем. Но благодаря тому, что в языке PHP применяется слабая типизация и поддерживается переменное количество параметров, появляется возможность обойти это ограничение. Если вам интересно, могу поделиться знаниями.
Пример полиморфизма в PHP
abstract class Publication <
// определяем правило, что все публикации должны печататься, т.е. иметь метод do_print()
abstract public function do_print();
>
class News extends Publication <
// переопределяем абстрактный метод печати
public function do_print() <
echo ‘
Новость
Объявление
Статья
//Наполняем массив публикаций объектами, производными от Publication
$publications[] = new News();
$publications[] = new Announcement();
$publications[] = new Article();
Главное здесь — последняя часть. Именно в ней заключается суть полиморфизма. Мы используем один и тот же код для объектов разных классов.
Теперь о том, как это можно применять на практике. Допустим, пользователь хочет отследить последние обновления публикаций, причем ему не важно, будут это статьи или новости или что-то еще.
С учетом того, что таблицы разные, поля в них тоже разные, удобнее всего получить отдельные списки для новостей и для статей. Но мы не можем их выводить отдельно — пользователю интересна временная последовательность. Поэтому мы сортируем данные, формируя, один большой массив объектов. Ну а далее, как и в примере выше, мы можем в рамках одного интерфейса вывести все объекты. Но при этом на экран новости и статьи будут выводиться немного по разному, например с разной иконкой или различным началом заголовка. Таким образом нам не нужно делать никаких проверок на предмет того, с чем мы работаем. Интерпретатор сделает это за нас.
Надеюсь теперь тема полиморфизма стала более понятной. Как отмечалось выше, если будет интересно, могу написать о переопределении методов, при котором ввод метода в действие осуществляется с учетом сигнатуры. Обращайтесь.
Полиморфизм для начинающих
Постановка задачи
Предположим, на сайте нужны три вида публикаций — новости, объявления и статьи. В чем-то они похожи — у всех них есть заголовок и текст, у новостей и объявлений есть дата. В чем-то они разные — у статей есть авторы, у новостей — источники, а у объявлений — дата, после которой оно становится не актуальным.
Самые простые варианты, которые приходят в голову — написать три отдельных класса и работать с ними. Или написать один класс, в которым будут все свойства, присущие всем трем типам публикаций, а задействоваться будут только нужные. Но ведь для разных типов аналогичные по логике методы должны работать по-разному. Делать несколько однотипных методов для разных типов (get_news, get_announcements, get_articles) — это уже совсем неграмотно. Тут нам и поможет полиморфизм.
Абстрактный класс
Грубо говоря, это класс-шаблон. Он реализует функциональность только на том уровне, на котором она известна на данный момент. Производные же классы ее дополняют. Но, пора перейти от теории к практике. Сразу оговорюсь, рассматривается примитивный пример с минимальной функциональностью. Все объяснения — в комментариях в коде.
// а этот метод должен напечатать публикацию, но мы не знаем, как именно это сделать, и потому объявляем его абстрактным
abstract public function do_print ();
>
Производные классы
Теперь можно перейти к созданию производных классов, которые и реализуют недостающую функциональность.
Теперь об использовании
Суть в том, что один и тот же код используется для обьектов разных классов.
Вот и все. Легким движением руки брюки превращаются в элегантные шорты :-).
Основная выгода полиморфизма — легкость, с которой можно создавать новые классы, «ведущие себя» аналогично родственным, что, в свою очередь, позволяет достигнуть расширяемости и модифицируемости. В статье показан всего лишь примитивный пример, но даже в нем видно, насколько использование абстракций может облегчить разработку. Мы можем работать с новостями точно так, как с объявлениями или статьями, при этом нам даже не обязательно знать, с чем именно мы работаем! В реальных, намного более сложных приложениях, эта выгода еще ощутимей.