Поліморфізм (програмування)
Поліморфі́зм (з грец. πολύς «багато» + μορφή «форма») — концепція в програмуванні та теорії типів, в основі якої лежить використання єдиного інтерфейсу для різнотипних сутностей або у використанні однакового символу для маніпуляцій над даними різного типу[джерело?].
На противагу поліморфізму, концепція мономорфізму вимагає однозначного зіставлення.
Типи поліморфізму
- Спеціалізований поліморфізм — коли функції з однаковою назвою реалізовують різну логіку для різних типів вхідних параметрів. Підтримується в багатьох мовах програмування через перевантаження функцій.
- Параметричний поліморфізм — коли код написаний без указування конкретного типу параметрів. В ООП це називається узагальнене програмування. Це основний тип поліморфізму в функційному програмуванні.
- Поліморфізм підтипів — коли під одним ім'ям може використовуватись декілька типів похідних від одного базового. Основний тип поліморфізму в ООП.
Взаємодія параметричного поліморфізму і підтипів призводить до понять варіативності та обмеженої квантифікації.
Приклади
- У контексті об'єктно-орієнтованого програмування найпоширенішим різновидом поліморфізму є здатність екземплярів підкласу грати роль об'єктів батьківського класу, завдяки чому екземпляри підкласу можна використовувати там, де використовуються екземпляри батьківського класу.[1]
- Прикладом спеціалізованого поліморфізму є бінарний оператор +, який може мати своїми аргументами дані різного типу: цілі числа, числа з рухомою комою, комплексні числа та навіть рядки:
- 1 + 2 — операнди цілого типу, результат цілого типу.
- 1.2 + 1.0e3 — операнди дійсних типів, результат дійсного типу
- «Бульдог» + «Носоріг» — операнди рядки, результат — конкатенований рядок
Спеціалізований поліморфізм
У наведеному далі прикладі на С++ в залежності від типу переданих даних будуть застосовуватись різні методи:
class Point {
private:
int x, y;
char x2,y2;
public:
void setXY(int _x, int _y)
{
x=_x;
y=_y;
}
void setXY(char _x, char _y)
{
x2=_x;
y2=_y;
}
};
Параметричний поліморфізм
Поліморфізм підтипів
Поліморфізм — один з трьох найважливіших механізмів об'єктно-орієнтованого програмування. Поліморфізм дозволяє створювати абстрактніші програми та підвищити коефіцієнт повторного використання коду[джерело?].
Спільні властивості об'єктів об'єднуються в систему, яку можуть називати по різному: інтерфейс, клас. Спільність має зовнішнє і внутрішнє вираження. Зовнішня спільність проявляється як однаковий набір методів з однаковими іменами і сигнатурами (типами аргументів і результатів)[джерело?].
Внутрішня спільність є однакова функціональність методів. Її можна описати інтуїтивно виразити у вигляді строгих законів, правил, яким повинні підкорятись методи[джерело?].
Наприклад:
#include <iostream>
class Felid {
public:
virtual void meow() = 0;
};
class Cat : public Felid {
public:
void meow() { std::cout << "Meowing like a regular cat! meow!\n"; }
};
class Tiger : public Felid {
public:
void meow() { std::cout << "Meowing like a tiger! MREOWWW!\n"; }
};
class Ocelot : public Felid {
public:
void meow() { std::cout << "Meowing like an ocelot! mews!\n"; }
};
void do_meowing(Felid *cat) {
cat->meow();
}
int main() {
Cat cat;
Tiger tiger;
Ocelot ocelot;
do_meowing(&cat);
do_meowing(&tiger);
do_meowing(&ocelot);
}
Статичний та динамічний поліморфізм
За часом вибору поліморфізм поділяють на статичний та динамічний:
- статичний поліморфізм (чи статична диспетчеризація) — якщо код, що буде виконуватись, вибирається під час компіляції;
- динамічний поліморфізм (чи динамічна диспетчеризація) — якщо код, що буде виконуватись, вибирається під час виконання програми (пізнє зв'язування).
Перевагами статичного поліморфізму є:
- кращий статичний аналіз коду компілятором,
- менший розмір коду (через кращу оптимізацію коду та відсутність таблиці віртуальних методів)
- швидший час виконання.
Зате динамічний поліморфізм:
- більш гнучкий,
- дозволяє качину типізацію,
- дозволяє використовувати динамічно приєднані бібліотеки для похідних типів.
Динамічний поліморфізм, зазвичай, це поліморфізм підтипів.
Статичний поліморфізм це ad hoc чи параметричний поліморфізм, хоча його також можна реалізувати через наслідування та шаблонне метапрограмування — це називається дивно рекурсивний шаблон.
Примітки
- Daniel P. Friedman, Mitchell Wand, Christopher T. Haynes (2001). Essentials of Programming Languages (англ.) (вид. друге). The MIT Press. ISBN 0-262-06217-8.