Только до 28.11
Вечерний «Путь в ИТ» с Иваном Ургантом
Кнопка закрыть топ-бар
ГлавнаяБлогПолиморфизм: суть, проблемы применения
Информационная безопасность автоматизированных систем
4 766
Время чтения: 16 минут

Полиморфизм: суть, проблемы применения

4 766
Время чтения: 16 минут
Сохранить статью:
Сохранить статью:
В статье рассказывается:   
  1. Что такое полиморфизм в ООП
  2. Польза полиморфизма в программировании
  3. Примеры полиморфизма в Python
  4. Проблемы полиморфизма подтипов в ООП
  5. Пройди тест и узнай, какая сфера тебе подходит:
    айти, дизайн или маркетинг.
    Бесплатно от Geekbrains

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

Зачем нужен? Данный принцип нужен для облегчения работы программиста. Например, ему не придется писать каждый раз новый код, а достаточно скопировать свойства одного для создания другого похожего. К примеру: на сайте есть статьи, объявления и новости. Коды для их создания похожи, но не идентичны. Объединяет их основа – контент, а какой он, это уже допиленные коды. Более подробно про полиморфизм мы рассказали ниже в статье.

Что такое полиморфизм в ООП

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

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

Что такое полиморфизм в ООП
Что такое полиморфизм в ООП

Механизм наследования предполагает использование следующей терминологии. Когда класс D наследует от класса B, последний является базовым для D, а D — производным от B. Этот механизм в объектно-ориентированном программировании не только дает возможность брать фрагменты программ за основу производства новых, но и позволяет совершать одни и те же действия над объектами разных классов при помощи одних и тех же выражений. Это и есть «полиморфизм».

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

  • Существуют абстрактные классы – это те, что содержат хотя бы один абстрактный метод (то есть требующий переопределения).
  • Создать объект абстрактного класса нельзя.
  • Производный класс имеет свойства и методы, унаследованные от базового, а также новые.
  • Метод, который в производном классе переопределяется, имеет название «виртуальный». В базовом абстрактном классе информация о нем отсутствует.
  • Абстрагирование заключается в определении метода в том месте, где имеются самые исчерпывающие данные о том, как он должен работать.

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

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

Написание одинаковых по сути методов для разных типов публикаций (get_news, get_announcements, get_articles) нельзя назвать правильным с точки зрения программирования. Именно здесь используется такое явление как полиморфизм.

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

Польза полиморфизма в программировании

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

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

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

Польза полиморфизма в программировании
Польза полиморфизма в программировании

Рассмотрим типы полиморфизма без отсылки к объектно-ориентированному программированию, то есть в более широком смысле.

  • Полиморфизм подтипов, или подтипизация (subtyping).
  • Параметрический полиморфизм, применяется в обобщённом программировании.
  • ad hoc полиморфизм, это перегрузка методов, основанная на той логике, что одинаковое имя метода может обозначать разные реализации в зависимости от своих параметров.

Примеры полиморфизма в Python

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

Пример № 1. Существует оператор “+”, часто используемый в программах, которые созданы на Python. Однако его можно применять разными способами.

ТОП-30 IT-профессий
2022 года с доходом
от 200 000 ₽
Команда GeekBrains совместно с международными специалистами по развитию карьеры подготовили материалы, которые помогут вам начать путь к профессии мечты.
Подборка содержит только самые востребованные и высокооплачиваемые специальности и направления в IT-сфере. 86% наших учеников с помощью данных материалов определились с карьерной целью на ближайшее будущее!

Скачивайте и используйте уже сегодня:

Александр Сагун
Александр Сагун
Исполнительный
директор Geekbrains
pdf иконка

Топ-30 самых востребованных и высокооплачиваемых профессий 2022

Поможет разобраться в актуальной ситуации на рынке труда

doc иконка

Подборка 50+ ресурсов об IT-сфере

Только лучшие телеграм-каналы, каналы Youtube, подкасты, форумы и многое другое для того, чтобы узнавать новое про IT

pdf иконка

ТОП 50+ сервисов и приложений от Geekbrains

Безопасные и надежные программы для работы в наши дни

pdf 3,7mb
doc 1,7mb
Уже скачали 16054 pdf иконка

Когда речь идет о целочисленных типах данных, “+” используется для сложения операндов:

  • number1 = 1

number2 = 2

print(number1 + number2)

В итоге программа покажет цифру 3.

При этом “+” можно применять и для конкатенации строк:

  • string1 = «Hello,»

string2 = «Otus!»

print(string1+» «+string2)

Получаем ожидаемый результат «Hello, Otus!».

Это один из самых простых примеров полиморфизма на Python: мы имеем только один оператор “+”, который осуществляет разные операции для разных типов данных.

Пример № 2. В «Пайтон» имеются функции, которые позволяют принимать аргументы различных типов – например, len().Рассмотрим подробнее, как это происходит.

  • print(len(«ООП-программирование»))

print(len([«Python», «Java», «C#», «Scala», «C++»]))

print(len({«Где изучить?»: «В Otus», «Как проходят занятия?»: «Онлайн»}))

Получаем такой результат:

20

5

2

Только до 28.11
Как за 3 часа
разбираться в IT
лучше, чем 90%
новичков и выйти на
доход в 200 000 ₽?
Приглашаем вас на бесплатный онлайн-интенсив «Путь в IT»! За несколько часов эксперты GeekBrains разберутся, как устроена сфера информационных технологий, как в нее попасть и развиваться.
Александр Волчек CEO GeekBrains

Интенсив «Путь в IT» поможет:

  • За 3 часа разбираться в IT лучше, чем 90% новичков.
  • Понять, что действительно ждет IT-индустрию в ближайшие 10 лет.
  • Узнать как по шагам c нуля выйти на доход в 200 000 ₽ в IT.
При регистрации вы получите в подарок:
pdf иконка

«Колесо компетенций»

Тест, в котором вы оцениваете свои качества и узнаете, какая профессия в IT подходит именно вам

doc иконка

«Критические ошибки, которые могут разрушить карьеру»

Собрали 7 типичных ошибок, четвертую должен знать каждый!

pdf иконка

Тест "Есть ли у вас синдром самозванца?"

Мини-тест из 11 вопросов поможет вам увидеть своего внутреннего критика

Хотите сделать первый шаг и погрузиться в мир информационных технологий? Регистрируйтесь и смотрите интенсив:
Только до 28 ноября
Осталось 17 мест

Дело в том, что функция len() умеет взаимодействовать с разными типами данных: строкой, списком, кортежем, множеством, словарем. В приведенном примере одна и та же функция возвратила специфичную информацию для каждого типа данных, а именно:

  • посчитала количество букв в слове «Программирование»;
  • посчитала количество слов в списке;
  • посчитала количество ключей в словаре.

Пример № 3. В Python, как и в остальных языках программирования, можно создавать классы, наследующие методы и атрибуты базового класса. Некоторые methods и attributes могут быть переопределены с целью их соответствия классу-потомку. Это называется переопределением (overriding). С помощью полиморфизма можно получать доступ к переопределенным методам и атрибутам с тем же именем, что и в родительском классе.

Рассмотрим пример переопределения такого рода.

from math import pi

class Shape:

def __init__(self, name):

self.name = name

def area(self):

pass

def fact(self):

return «Я — двумерная фигура»

def __str__(self):

return self.name

class Square(Shape):

def __init__(self, length):

super().__init__(«Квадрат»)

self.length = length

def area(self):

return self.length**2

def fact(self):

return «Любой угол квадрата равен 90 градусов.»

class Circle(Shape):

def __init__(self, radius):

super().__init__(«Круг»)

self.radius = radius

def area(self):

return pi*self.radius**2

a = Square(5)

b = Circle(8)

print(b)

print(b.fact())

print(a.fact())

print(b.area())

Смотрим на вывод программы:

  • Круг

Я — двумерная фигура

Любой угол квадрата равняется 90 градусам.

201.06192982974676

Этот вариант полиморфизма работает следующим образом. В данном случае в работе кода были использованы методы __str__(), их не переопределили в дочерних классах, то есть они применяются прямо из родительского класса. Питоновский интерпретатор автоматически определил, что метод fact() для объекта a (class Square) является переопределенным. В итоге применяется тот метод, который был определен в классе-наследнике.

Метод fact() для объекта b не является переопределенным, поэтому используется метод с таким же именем из родительского класса (Shape).

Стоит сказать, что Python не поддерживает такой вариант переопределения метода как создание методов с таким же именем, но с различными типами аргументов.

Проблемы полиморфизма подтипов в ООП

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

У ООП есть огромное количество недостатков, которые негативно влияют на всю отрасль в целом. И начинающие программисты должны их знать. К сожалению, объектно-ориентированное программирование, несмотря на свои неоспоримые недостатки, до сих пор является базой для вполне перспективных языков программирования.

Рассмотрим основные принципы ООП.

  • Инкапсуляция. Независимость объектов, внутри каждого из которых находятся необходимые данные.
  • Наследование. Возможность использовать один и тот же код так, что один объект может приобретать свойства другого.
  • Полиморфизм подтипов. Свойство системы, благодаря которому объекты с одинаковым интерфейсом могут использоваться без информации их о типе и внутренней структуре.

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

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

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

Проблемы полиморфизма подтипов в ООП
Проблемы полиморфизма подтипов в ООП

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

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

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

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

Оцените статью
Рейтинг: 5
( голосов 3 )
Поделиться статьей
Добавить комментарий

Забрать
гарантированный
подарок

Получите бесплатно подборку файлов от GeekBrains:

Осталось 17 мест

Поздравляем! Вы выиграли 4 курса по ИТ профессиям. Чтобы закрепить подарок и получить к нему доступ, заполните информацию в открывшемся окне

×
Петр Озеров
Петр Озеров печатает ...