Поліморфізм в 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
'Іван'
>>>