double arrow
Конец описания

19) Сложный полиморфизм или создание полиморфных объектов.При сложном полиморфизме конкр аспект полиморфного метода также определен типом объекта, но только на этапе компиляции, а на этапе выполения программы, т.е. при позднем связывании. Полиморфными объектами или полиморфными переменными называются переменные, которым в процессе выполнения программы может быть присвоено значение, тип которого отличается от типа переменной. В языках с жесткой типизацией такая ситуация может возникнуть:

1) при передаче объекта типа класса-потомка в качестве фактического параметра подпрограмме, в которой этот параметр описан, как параметр типа класса-родителя (явно - в списке параметров или неявно – в качестве внутреннего параметра, используемого при вызове методов - self или this);

2) при работе с указателями, когда указателю на объект класса-родителя присваивается адрес объекта класса-потомка.

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

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

С помощью механизма позднего связывания реализуется оперативная перестройка программы в соответствии с типами используемых объектов.




Поясним сказанное на примере.

Пример 1.10. Сложный полиморфизм

Пусть родительский класс содержит два метода Out и Print, один из которых вызывает другой. Класс-потомок наследует метод Out, но имеет собственный метод Print. Метод Out наследуется и может быть вызван как для объекта класса-родителя, так и для объекта класса-потомка (рис. 1.22).

Рис. 1.22. Иерархия классов примера 1.10

При вызове метода Out для объекта класса-потомка необходимо обеспечить, чтобы этот метод вызывал метод Print потомка, а не родителя (рис. 1.23). Определить, для объекта какого класса: родителя или потомка вызывается метод Out, можно только на этапе выполнения. Следовательно, для метода Print необходимо обеспечить позднее связывание. Если определение адреса метода Print происходило бы на этапе компиляции программы, то и для объекта родительского класса, и для объекта класса-потомка из метода Out вызывался бы метод Print класса-родителя. Описание метода Print как метода, для которого запрещается определение адреса на этапе компиляции, приведет к тому, что адрес метода Print будет определяться в процессе выполнения программы. В этот момент уже будет известно, объект какого класса вызывает метод Out, и будет вызываться метод Print именно этого класса.



20) Виртуальные методы как средства реализации сложного полиморфизма. Реализация механизма позднего связывания осуществляется с использованием специальной таблицы, получившей название таблицы виртуальных методов (ТВМ). ТВМ создается для каждого класса, имеющего собственные или наследующего виртуальные методы. Она содержит адреса виртуальных методов (рис. 1.24). Объекты таких классов содержат адрес ТВМ своего класса. При вызове виртуального метода для объекта происходит обращение к ТВМ класса, по которой и определяется требуемый метод.

Рис. 1.24. Реализация механизма позднего связывания

При использовании полиморфных объектов возникают проблемы с доступом к полям объекта, описанным в классе-потомке: указатель на объект класса-родителя связан с описанием полей класса-родителя, и поля, описанные в классе-потомке, для него «невидимы»






Сейчас читают про: