Встречается на 26% собеседований по Python
Что такое полиморфизм
Полиморфизм — это способность функции или метода обрабатывать данные разных типов, а также возможность схожих типов данных, связанных иерархией наследования, иметь различные реализации. В программировании выделяют три основные формы полиморфизма: специальный (ad-hoc), параметрический и полиморфизм подтипов. Чаще всего под полиморфизмом подразумевают именно полиморфизм подтипов, который достигается через наследование и переопределение методов.
Формы полиморфизма
- Специальный (ad-hoc) полиморфизм — позволяет одной и той же функции обрабатывать разные типы, но с разной реализацией. В языках вроде Java или C++ это реализуется через перегрузку методов (method overloading). В Python перегрузки нет, но её частично имитируют с помощью
@singledispatchили проверок типа внутри функции. - Параметрический полиморфизм — функция или тип работают с любым типом данных, не меняя своей реализации. В статически типизированных языках это дженерики (например,
List<T>в Java). В Python параметрический полиморфизм проявляется естественно из-за динамической типизации: функция может принимать аргументы любого типа, если она не использует специфичные для типа операции. - Полиморфизм подтипов — основан на наследовании: класс-наследник может переопределять методы родителя, и вызов метода через ссылку на родительский тип будет использовать реализацию наследника. Это ключевая концепция ООП, позволяющая писать код, работающий с абстракциями, а не с конкретными классами.
Пример на Python
В Python полиморфизм подтипов реализуется через наследование и переопределение методов:
python
class Animal:
def speak(self):
raise NotImplementedError
class Dog(Animal):
def speak(self):
return "Woof"
class Cat(Animal):
def speak(self):
return "Meow"
# Функция принимает любой объект Animal
# и вызывает его метод speak — это и есть полиморфизм
def make_sound(animal: Animal):
print(animal.speak())
make_sound(Dog()) # Woof
make_sound(Cat()) # MeowЗдесь make_sound не знает, какой именно подтип Animal ей передадут, но благодаря полиморфизму вызов speak() сработает корректно для любого наследника.
Подводные камни и особенности
- В Python нет строгой типизации, поэтому полиморфизм подтипов работает на основе «утиной типизации»: если объект имеет нужный метод, он может быть использован, даже если не наследуется от ожидаемого класса. Это даёт гибкость, но может приводить к ошибкам, если метод вызывается с объектом, не имеющим нужной реализации.
- Перегрузка методов в Python отсутствует, но можно использовать
functools.singledispatchдля создания функций с разным поведением в зависимости от типа первого аргумента. - Параметрический полиморфизм в Python не требует явных дженериков, но с появлением type hints (например,
List[int]) можно частично имитировать статическую типизацию, хотя это не влияет на выполнение.
Коротко
- Полиморфизм — способность обрабатывать разные типы данных единообразно.
- Три формы: специальный (перегрузка), параметрический (дженерики), подтипов (наследование).
- В Python чаще всего используется полиморфизм подтипов через переопределение методов.
- Утиная типизация делает полиморфизм в Python более гибким, но требует осторожности.
как отвечать на вопрос
пример собеседования
фреймворки на собеседовании
типичные вопросы junior
интервью вопросы и ответы
