Найти в Дзене
Old Programmer

Полиморфизм в наследовании (язык программирования C++)

Мой канал Old Programmer, а здесь: Программирование. Тематическое оглавление моего Zen-канала (Old Programmer). А здесь материалы по ООП. Ссылка на все материалы по языкам программирования C и C++. Мне писали замечание, что много программ и некоторые довольно длинные. Трудно для восприятия. Но программы то вообще бывают довольно длинными, а кроме того, хочется чтобы программа все же была бы рабочей и ее можно было запустить и поработать с ней. Сегодня в статье у меня аж четыре программы и я их сократил до предела (убрал конструкторы и деструкторы), но все они рабочие и что-то демонстрируют. Полиморфизм в программировании (C++) Если вы посмотрите слово полиморфизм в литературе, то разными авторами даже в области программирования это понятие объясняется по-разному. В частности к полиморфизму относят и такое явление как перегрузка. Я же склонен рассматривать полиморфизм в основном в части наследования. В этом случае полиморфизм означает, что класс наследник имеет тот же интерфейс, что и

Мой канал Old Programmer, а здесь: Программирование. Тематическое оглавление моего Zen-канала (Old Programmer). А здесь материалы по ООП. Ссылка на все материалы по языкам программирования C и C++.

Мне писали замечание, что много программ и некоторые довольно длинные. Трудно для восприятия. Но программы то вообще бывают довольно длинными, а кроме того, хочется чтобы программа все же была бы рабочей и ее можно было запустить и поработать с ней. Сегодня в статье у меня аж четыре программы и я их сократил до предела (убрал конструкторы и деструкторы), но все они рабочие и что-то демонстрируют.

  • Список разделов канала Old Programmer, канала о программировании и программистах

Полиморфизм в программировании (C++)

Если вы посмотрите слово полиморфизм в литературе, то разными авторами даже в области программирования это понятие объясняется по-разному. В частности к полиморфизму относят и такое явление как перегрузка. Я же склонен рассматривать полиморфизм в основном в части наследования. В этом случае полиморфизм означает, что класс наследник имеет тот же интерфейс, что и родительский класс, но с адаптированными для наследника методами (разные объекты с одним интерфейсом).

Хочу напомнить, что в C++ объекты можно определять, как обычные переменные и тогда они создаются во время компилирования. Но есть возможность создавать объекты и во время исполнения, динамически, используя оператор new. Применительно к наследованию говорят о раннем и позднем связывании. И вот тут могут возникнуть интересные ситуации, которые я сегодня и рассмотрю. Все программы компилировались мной с помощью g++.

В программе main250.cpp представлено статическое создание объекта b от класса B, который является наследником класса A. Типичный полиморфизм в данном случае заключается в том, что у обоих классов есть метод a1 с одним и тем же именем. При запуске программы выводится 100, т.е. работает метод класса B. Здесь нет ничего не обычного, ведь объект создается еще на стадии компиляции.

Программа main250a.cpp это слегка переделанная программа main250.cpp. Объект класса B создается динамически. Но для компилятора здесь нет никаких проблем, так как класс B является наследником класса A, а b указывает на объект класса B. Естественно, при выполнении программа выдает 100.

В программе main250b.cpp мы имеем совсем другую ситуацию. У нас есть указатель на объект класса A. А далее мы осуществляем преобразование типов b = (A*) new B(); . Т.е. создаем объект B и преобразуем его к типу A. Результат программы будет 20. Т.е. выполнилcя метод класса A. По смыслу преобразования типов, компилятор вроде бы был прав. Но с другой стороны, мы создали объект класса B. Кроме того, ведь между классами A и B могут быть еще наследники и логично было бы иметь возможность использовать один указатель для объектов разного типа (связанных наследованием), так чтобы выполнялись методы именно созданного объекта.

И вот тут на помощь приходят виртуальные методы. Смотрим программу main250c.cpp. Обратите внимание на модификатор virtual, который используется для определения методов. И о чудо! Результат выполнения программы 100, т.е. сработал метод класса B. Заработал правильный полиморфизм. Теперь мы можем взять один указатель и использовать его для объектов разных классов, при этом виртуальные методы будут исполняться именно для создаваемых объектов. Конечно это не все о полиморфизме, далеко не все, но очень важный его элемент.

Для того, чтобы еще глубже осознать вот это понятие полиморфизма с использованием виртуальных методов, я бы вам советовал первые три строки функции main (main250c.cpp) дополнить строками:

b = (B*) new B();
b->a1(10);
B * bb;
bb = (B*) new A();
bb->a1(10);
bb = (B*) new B();
bb->a1(10);

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

Вопрос виртуальных методов и полиморфизма не закончен, в одном из следующих уроков я к нему возвращусь.

Мой канал Old Programmer в вашем распоряжении, подписывайтесь на него. Пока! И вы забыли поставить ЛАЙК, не так ли?

Фрагмент программы
Фрагмент программы