Полиморфизм – это свойство, позволяющее использовать один интерфейс для целого класса действий. В качестве простого примера полиморфизма можно привести руль автомобиля. Для руля (т.е. интерфейса) безразлично, какой тип рулевого механизма используется в автомобиле. Другими словами, руль работает одинаково, независимо от того, оснащен ли автомобиль рулевым управлением прямого действия (без усилителя) или механизмом реечной передачи. Если вы знаете, как обращаться с рулем, то сможете вести автомобиль любого типа.
Фундамент, на котором в C++ строится поддержка полиморфизма, состоит из механизма наследования и указателя на базовый класс. Конкретным средством, которое в действительности позволяет реализовывать полиморфизм, является виртуальная функция.
Виртуальная функция – это функция, которая объявляется в базовом классе с использованием ключевого слова virtual и переопределяется в одном или нескольких производных классах. В результате каждый производный класс может получить свою собственную версию виртуальной функции. При переопределении виртуальной функции в производном классе использовать ключевое слово virtual не обязательно. Класс, который включает виртуальную функцию, называется полиморфным. Если в базовом классе определены виртуальные функции, то к производным классам также применим приведенный термин. Функция, объявленная как виртуальная, остается такой независимо от того, через, сколько уровней производных классов она может пройти.
В языке C++ поддерживается использование чисто виртуальных функций. Их главной отличительной чертой является отсутствие тела функции. Чтобы объявить чисто виртуальную функцию используется следующий формат:
virtualтипимя_функции(список_параметров) = 0;
Класс, в котором объявляется чисто виртуальная функция, называется абстрактным и представляет собой пустой бланк, который в случае использования необходимо заполнить. Производный класс, по сути, и является этим заполнителем. Он должен переопределить все виртуальные функции и получить их собственную реализацию.
Для реализации работы средства управления автомобилем, можно создать абстрактный класс Steering, в котором будут объявлены виртуальные функции поворота. В классе PowerSteering, производном от Steering, нужно переопределить виртуальные функции поворота. Если сделать указатель Steering* steering и присвоить ему адрес объект powerSteering класса PoweSteering, то при вызове функции поворота steering->left() система автоматически подберет функцию в соответствии с адресуемым объектом. Другими словами происходит автоматический вызов функция класса PowerSteering через указатель на родительский класс.
Пример 1.4Вызов функции через указатель на родительский класс.
class Steering //класс руль
{
public:
virtual void right() //виртуальная функция
{ //поворота вправо
}
virtual void left() //виртуальная функция
{ //поворота влево
}
}
class PowerSteering : public Steering //наследование класса
{ //Steering
public:
void right() //переопределение виртуальной функции right
{
}
void left() //переопределение виртуальной функции left
{
}
}
int main()
{
Steering* steering; // Поворот налево
PowerSteering powerSteering; // происходит при вызове