Перейти до змісту

Поліморфізм в Python

Найпростіший приклад поліморфізму в Python — оператор "плюс". Для різних типів даних буде виконуватись різна дія:

  • для даних типу int — додавання
  • для даних типу str — конкатенація

Поліморфізм проявляється при використанні функцій. Наприклад функції len() можна передати символьний рядок, список, словник, багато ще чого.

В класах поліморфізм відіграє ключову роль. У декількох класів, навіть не пов'язаних успадкуванням, може бути свій метод __init__() або будь-який інший. Який саме з методів __init__() буде викликано, і що саме він "зробить", залежить від належності об'єкта до того чи іншого класа.

При успадкуванні поліморфізм дозволяє отримувати доступ до перевизначених атрибутів класа, які мають таке ж саме ім'я, що і в базовому класі.

Качина типізація

Качина (латентна) типізація (Duck typing) — різновид динамічної типізації, застосовуваної в деяких мовах програмування, коли межі використання об'єкта визначаються його поточним набором методів і властивостей, на противагу успадкуванню від певного класу.

Тобто вважається, що об'єкт реалізує інтерфейс, якщо він містить всі методи цього інтерфейсу, незалежно від зв'язків в ієрархії наслідування та приналежності до якогось конкретного класу.

Назва терміна походить від англійського «duck test» («качиний тест»), який в оригіналі звучить так:

If it looks like a duck, swims like a duck and quacks like a duck, then it probably is a duck.

(Якщо воно виглядає як качка, плаває як качка і крякає як качка, то це напевно і є качка).

Смисл качиної типізації полягає у послабленні типів. Замість того, щоб піклуватись про точний клас об'єкта, ми піклуємось про те, які методи для нього можна викликати і які операції над ним можна виконувати. Таким чином, звичним ділом стає просто передати об'єкт методу, знаючи, що при неправильному використанні буде викинуто виняток (exception).

Наприклад:

def method(obj):
   obj.start()

При качиній типизації ми не піклуємось про тип об'єкта obj, нам лише важливо, що у нього є метод start. Якщо ж такого метода немає, то отримаємо виняток.

Ще приклад:

>>> class Duck:
...     def quack(self):
...         print('Кря!')
...
>>> class Person:
...     def __init__(self, name):
...         self._name = name
...     def quack(self):
...         print('Людина імітує крякання: "Кря!"')
...     @property
...     def name(self):
...         return self._name
...
>>> donald = Duck()
>>> john = Person('Іван')
>>> donald.quack()
Кря!
>>> john.quack()
Людина імітує крякання: "Кря!"
>>> john.name
'Іван'
>>>
Back to top