Top.Mail.Ru

Язык С++. Полиморфизм

 Полиморфизм – свойство, которое позволяет использовать одно и тоже имя функции для решения двух и более схожих, но технически разных задач. Полиморфизм –  возможность замещения методов объекта родителя методами объекта-потомка, имеющих то же имя.

Полиморфизм по-гречески означает «много форм». Объекты, имеющие общего предка, могут принимать разные формы, оставаясь при этом схожими.

Чтобы использовать полиморфизм, необходимо чтобы:

1)      все классы-потомки являлись наследниками одного и того же базового класса

2)      функция, реализующая метод,  должна быть объявлена виртуальной в базовом классе

Виртуальным называется метод, ссылка на который вычисляется на этапе выполнения программы.

Доступ к обычным методам через указатели

Рассмотрим пример, когда базовый и производные классы содержат функции с одни и тем же именем, и к ним обращаются с помощью указателей, но без использования виртуальных функций:

A, B, Base – это типы. Указатели на объекты производных классов совместимы по типу с указателями на объекты базового класса.

Base *ptr;     ptr=&a;           ptr=&b;        

Однако, указатели производных классов между собой не совместимы!

 Пример:

 A *ptr;    ptr=&a;

               ptr=&b;      // указатель класса A не совместим с указателем класса B!!! 

 Теперь необходимо понять, какая собственно функция выполняется в этой строчке

Это функция Base::show()  или A::show()  или B:show()?

Результат выполнения дает простой ответ

Base

Base

 Всегда выполняется метод базового класса. Компилятор  не смотрит на содержимое указателя, а выбирает метод, определяемый типом указателя!!

Доступ к виртуальным методам через указатели

Сделаем одно маленькое изменение в нашей программе: поставим ключевое слово virtual  перед объявлением функции show() в базовом классе.

На выходе имеем:

Class A

Class B

Теперь выполняются методы производных классов. Один и тот же вызов ставит на выполнение разные функции в зависимости от содержимого указателя  ptr.

Если метод в базовом классе объявлен как виртуальный, то компилятор выбирает  метод по содержимому указателя, а не по типу указателя, как было в первом примере.

Абстрактные классы и чисто виртуальные методы

Базовый класс, объекты которого никогда не будут реализованы называется абстрактным классом. Такой класс может существовать с единственной целью – быть родительским классом к производным классом, объекты которых будут реализованы.

Для того чтобы сделать базовый класс абстрактным, достаточно ввести в класс хотя бы одну чисто виртуальную функцию.

Чисто виртуальная функция – это функция, после объявления которой добавлено выражение =0.

 

Пример: Объявить абстрактный класс person. Объявить два производных класса – student и teacher. В каждом из классов объявить метод, с помощью которого можно создать список выдающихся педагогов и студентов. Студентов со средним баллом больше 4 и педагогов с числом публикаций более 50 статей считать выдающимися.

Подведем итоги:

  1.  Полиморфизм позволяет использовать одно и то же имя функции для решения двух и более схожих, но технически разных задач.
  2. Если метод в базовом классе объявлен как виртуальный, то компилятор выбирает  метод по содержимому указателя, а не по типу указателя.
  3. Чтобы сделать базовый класс абстрактным, достаточно ввести в класс хотя бы одну чисто виртуальную функцию.
  4. Если  в базовом классе объявлена чисто виртуальная функция, в производных классах объявление чисто виртуальных функций запрещено.