Полиморфизм (polymorphism) (от греческого polymorphos) - это свойство, которое позволяет одно и то же имя использовать для решения двух или более схожих, но технически разных задач. Целью полиморфизма, применительно к объектно-ориентированному программированию, является использование одного имени для задания общих для класса действий. Выполнение каждого конкретного действия будет определяться типом данных.
В более общем смысле, концепцией полиморфизма является идея "один интерфейс, множество методов". Это означает, что можно создать общий интерфейс для группы близких по смыслу действий. Преимуществом полиморфизма является то, что он помогает снижать сложность программ, разрешая использование того же интерфейса для задания единого класса действий. Выбор же конкретного действия, в зависимости от ситуации, возлагается на компилятор. Вам, как программисту, не нужно делать этот выбор самому. Нужно только помнить и использовать общий интерфейс.
Ключевым в понимании полиморфизма является то, что он позволяет манипулировать объектами различной степени сложности путём создания общего для них стандартного интерфейса для реализации похожих действий.
В объектно-ориентированных языках класс является абстрактным типом данных. Полиморфизм реализуется с помощью наследования классов и виртуальных функций. Класс-потомок наследует методы класса-родителя, а реализация, в результате переопределения метода, этих методов может быть другой, соответствующей специфике класса-потомка. Другие функции могут работать с объектом класса-родителя, но при этом вместо него во время исполнения будет подставляться один из классов-потомков. Это называется поздним связыванием.
Основные концепции:
1. Полиморфизм представляет собой способность объекта изменять форму во время выполнения программы.
2. Для создания полиморфных объектов программа должна использовать виртуальные (virtual) функции.
3. Виртуальная (virtual) функция — это функция базового класса, перед именем которой стоит ключевое слово virtual.
4. Любой производный от базового класс может использовать или перегружать виртуальные функции.
5. Для создания полиморфного объекта следует использовать указатель на объект базового класса.
Предположим, например, что требуется написать программу, которая эмулирует телефонные операции. Сюда входят такие операции как набор номера, звонок, разъединение и индикация занятости. С помощью этих операций можно определить следующий класс:
#include <stdio.h>
#include <iostream.h>
#include <conio.h>
class phone {
public:
void dial(char *number) {cout<<"Connecting..."<<endl;}//метод соединение
Программа не делает различий между дисковым и кнопочным телефонами, также она не поддерживает платные телефоны (пользователь должен заплатить 250 руб, чтобы позвонить).
Поскольку нам известно наследование, то необходимо создать классы touch_tone(кнопочный) и pay_phone(платный) из класса phone, как показано ниже:
class touch_tone : public phone {
public:
void dial(char *number){ cout<<"Connecting by touch_tone..."<<endl;}
touch_tone(char *number) : phone(number){ }
};
class pay_phone: public phone {
public:
void dial(char *number) {
cout<<"Pay "<< amount <<" r"<<endl<<"Connecting... "<< number <<endl;}
pay_phone(char *number, int amount) : phone(number) {
pay_phone::amount = amount;
}
private:
int amount;
};
Как видно, классы touch_tone и pay__phone определяют свой собственный метод dial. Следующая программа использует эти классы для создания объектов rotary, touch_tone и pay_phone:
void main (void) {
phone rotary("303-555-1212");
rotary.dial("602-555-1212");
touch_tone telephone("555-1212");
telephone.dial("212-555-1212");
pay_phone city_phone("555-1111", 250);
city_phone.dial("212-555-1212");
}
Если вы откомпилируете и запустите эту программу, на экране дисплея появится следующий вывод: