Полиморфизм как один из принципов ООП. Понятие виртуальных функций.
Полиморфизм (polymorphism) (от греческого polymorphos) - это свойство, которое позволяет одно и то же имя использовать для решения двух или более схожих, но технически разных задач. Целью полиморфизма, применительно к объектно-ориентированному программированию, является использование одного имени для задания общих для класса действий. Выполнение каждого конкретного действия будет определяться типом данных. Например для языка Си, в котором полиморфизм поддерживается недостаточно, нахождение абсолютной величины числа требует трёх различных функций: abs(), labs() и fabs(). Эти функции подсчитывают и возвращают абсолютную величину целых, длинных целых и чисел с плавающей точкой соответственно. ВС++ каждая из этих функций может быть названа abs(). Тип данных, который используется при вызове функции, определяет, какая конкретная версия функции действительно выполняется. ВС++ можно использовать одно имя функции для множества различных действий. Это называется перегрузкой функций (functionoverloading).
В более общем смысле, концепцией полиморфизма является идея "один интерфейс, множество методов". Это означает, что можно создать общий интерфейс для группы близких по смыслу действий. Преимуществом полиморфизма является то, что он помогает мнижать сложность программ, разрешая использование того же интерфейса для задания единого класса действий. Выбор же конкретного действия, в зависимости от ситуации, возлагается на компилятор. Вам, как программисту, не нужно делать этот выбор самому. Нужно только помнить и использовать общий интерфейс. Пример из предыдущего абзаца показывает, как, имея три имени для функции определения абсолютной величины числа вместо одного, обычная задача становится более сложной, чем это действительно необходимо.
Полиморфизм может применяться также и к операторам. Фактически во всех языках программирования ограниченно применяется полиморфизм, например, в арифметических операторах. Так, в Си, символ + используется для складывания целых, длинных целых, символьных переменных и чисел с плавающей точкой. В этом случае компилятор автоматически определяет, какой тип арифметики требуется. ВС++ вы можете применить эту концепцию и к другим, заданным вами, типам данных. Такой тип полиморфизма называется перегрузкой операторов (operatoroverloading).
Ключевым в понимании полиморфизма является то, что он позволяет вам манипулировать объектами различной степени сложности путём создания общего для них стандартного интерфейса для реализации похожих действий.
ВС++ виртуальные функции (virtualfunctions) позволяют использовать полиморфизм (polymorhpism) классов. Так как виртуальные функции могут использоваться только внутри классов, то иногда их называют виртуальными методами (virtualmethods).
Чтобы объявить функцию как виртуальную, необходимо добавить ключевое слово virutal перед именем возвращаемого типа:
class Base
{
public:
virtual void Method ()
{
cout<< "Базовый класс\n";
}
};
Вносить изменения в производные классы не нужно. Хотя можно и там добавить ключевое слово virtual (это не обязательно). Теперьпосмотримнанашкод:
Base* b = new Derived;
Derived* d = new Derived;
b->Method();
d->Method();
//-------- Вывод:
Производный класс
Производный класс
То что нужно! Теперь вызывается метод того класса, на который на самом деле указывает указатель. Наконец-то мы можем создать массив указателей на базовый класс и размещать там объекты любого производного класса:
BaseMonster* monsters[3];
monsters[0] = new MonsterA;
monsters[1] = new MonsterB;
monsters[2] = new MonsterC;
for (inti=0;i<3;++i)
monsters[i]->attack();
Несколько замечаний по виртуальным функциям:
Виртуальные функции используются только в классах. Поэтому часто используется название - виртуальные методы.
В массивах указателей на базовый класс можно хранить объекты только полиморфных типов (базовый и все производные).
В массив нужно объединять только те объекты, которые обладают методами с одинаковыми названиями, но разной реализацией.
Как видите, пользоваться виртуальными методами очень просто. Теперь давайте разберёмся, какие механизмы стоят за виртуальными функциями.