Чат PHP-разработчиков
Полиморфизм в PHP

Полиморфизм в PHP

В этом уроке мы поговорим о последнем из трёх китов ООП – полиморфизме. В этом уроке нам придется отойти от примеров с котиками и собачками, и немного удариться в абстракции.

Однако перед этим давайте вспомним конструкцию instanceof. Она позволяет узнать, является ли объект экземпляром какого-то класса, либо что он реализует какой-либо интерфейс. Возвращает true или false.

Код доступен только после покупки курса ООП в PHP.

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

Код доступен только после покупки курса ООП в PHP.

При этом если проверить объект дочернего класса, является ли он объектом родительского класса, то мы получим true.

Код доступен только после покупки курса ООП в PHP.

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

Код доступен только после покупки курса ООП в PHP.

Согласитесь, это вполне логично.

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

Как мы помним, методы объектов родительских классов у нас доступны и в дочерних – они наследуются. Соответственно мы можем быть уверены, что эти же методы есть и у дочерних объектов. Конкретно в нашем примере – у объектов класса B будет метод sayHello(), унаследованный от A.

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

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

Это свойство, благодаря которому мы можем зависеть не от конкретной реализации (проще говоря конкретного класса), а от абстракции (интерфейса), и есть – полиморфизм.

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

Переопределение методов

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

Код доступен только после покупки курса ООП в PHP.

Однако, мы можем переопределить этот метод в классе B. Для этого мы описываем метод с таким же названием и описываем в нём свою логику:

Код доступен только после покупки курса ООП в PHP.

Мы также можем вызвать родительский метод в дочернем при помощи слова parent и двойного двоеточия.

Код доступен только после покупки курса ООП в PHP.

Мы вызвали родительский метод, и дополнили его функционал. Так часто приходится делать в реальных проектах. Буквально через пару уроков вы столкнетесь с более понятными примерами того, для чего всё это нужно. Но пока что мы должны изучить базу на немного искусственных примерах. К сожалению, придумать что-то более интересное я не смог.

И ещё один примерчик, тоже искуственный.

Код доступен только после покупки курса ООП в PHP.

Как думаете, что выведет этот код?

A или B?

Не знаю, что вы ответили, но он в любом случае выведет B. Внутри метода method1() будет вызван тот метод method2(), который определён для класса, в котором его выполняют. То есть $this не привязан напрямую к классу A. Когда мы вызываем method1() у экземпляра класса B, то $this внутри него будет связан с классом B, и вызовется метод method2(), определенный именно в классе B.

И это – тоже полиморфизм. $this привязывается к объекту, в котором код выполняется, а не там, где он был описан.

На этом с полиморфизмом пока всё, если что-то непонятно – пишите в комментах.

Читайте также
Комментарии (6)


DmitryGavrilov

Спасибо классный урок, как работает разобрался, однако сформулировать для себя что именно такое полиморфизм до конца не смог)

ivashkevich

Главное что понял как работает, потом сформулируешь, программируй давай)

lig7771991@list.ru

В двух словах, если метод переопределен в дочернем классе, то по ссылке $this на объекте вызовется именно он, если не переопределен, то вызовется родительский.

ivashkevich

Суть не только в этом. Прежде всего это возможность зависеть от абстракций, а не от реализаций.

lig7771991@list.ru

Безусловно, просто с ходу понять эти абстракции очень не просто...

ivashkevich

Сходу да, со временем придёт =)

Популярное за сутки
Сейчас читают
Логические задачи с собеседований