При чтении предыдущего раздела вы, возможно, задали себе
вопрос: "Если любой порожденный от типа параметра тип может пере-
даваться в качестве параметра, то как же пользователь параметра
узнает, какой тип объекта он получил?" Фактически, пользователь
явно этого и не знает. Точный тип фактического параметра не из-
вестен во время компиляции. Фактический параметр может быть объ-
ектом любого дочернего от параметра-переменной типа, и именно по-
этому он называется полиморфическим объектом.
Теперь, чем же именно хорош полиморфический объект? Прежде
всего полиморфические объекты позволяют обрабатывать объекты, чей
тип неизвестен на момент компиляции. Это общее замечание настоль-
ко ново для образа мышления Паскаля, что пример для вас не поя-
вится незамедлительно. (Со временем вы будете удивлены, насколько
естественно это выглядит. То есть, когда вы действительно станете
объектно-ориентированным программистом.)
Предположим, что вы написали инструментальное средство для
вычерчивания графиков, поддерживающее многочисленные типы фигур:
точки, окружности, квадраты, прямоугольники, кривые и т.д. В ка-
честве части этого инструментального средства вы хотите написать
программу, которая будет перемещать графическую фигуру по экрану
с помощью устройства типа "мышь".
При старом способе необходимо было написать отдельную проце-
дуру перемещения для каждого типа графической фигуры, поддержива-
емой инструментальным средством. Вы должны были бы написать
DragButterfly, DragBee, DragMoth и т.д. Несмотря на то, что стро-
гая типизация (проверка типов) Паскаля позволяла это (и не забы-
вайте, что всегда существуют способы обойти строгую типизацию),
различия между типами графических фигур едва ли позволили бы на-
писать действительно общую программу перемещения.
В конце концов, пчела имеет полоски и жало, бабочка имеет
большие цветные крылья, а стрекоза имеет переливчатые цвета,
хвост, да что говорить...
С этой точки зрения, "сообразительные" программисты, работа-
ющие на Турбо Паскале, сделают шаг вперед и скажут: "Поступайте
так: передайте запись о крылатом насекомом процедуре DragIt в ка-
честве ссылки указателя общего вида. В процедуре DragIt проверяй-
те свободное поле по фиксированному смещению внутри записи о
крылатом насекомом для определения, какого вида это насекомое, а
затем сделайте переход с помощью оператора case:
case FigureIDTag of
Bee : DragBee;
Butterfly : DragButterfly;
Dragonfly : DragDragonfly;
Mocquito : DragMocquito;
.
.
.
Ну, размещение семнадцати маленьких чемоданчиков внутри од-
ного большого является незначительным шагом вперед, но в чем же
заключается проблема, ожидающая нас на этом пути?
Что случится, если пользователь инструментального средства
определит несколько новых типов крылатых насекомых?
В самом деле, что? Что если пользователь захочет работать со
среднеазиатскими фруктовыми мухами? В вашей программе нет типа
Fruitfly, поэтому DragIt не содержит метки Fruitfly в операторе
case и, следовательно, отвергнет перемещение нового рисунка
Fruitfly. Будучи представленным процедуре DragIt, Fruitfly будет
выпадать из оператора case в ветвь else этого оператора как "не-
распознанное насекомое".
Откровенно говоря, создание для продажи инструментального
средства без исходного кода страдает этой проблемой. Инструмен-
тальное средство может работать только с типами данных, которые
"известны" ему, т.е. которые определены разработчиком инструмен-
тального средства. Пользователь инструментального средства оказы-
вается бессильным перед расширением его функций в направлении, не
предвиденном разработчиком. То, что пользователь купил, то он и
получил. И точка.
Выходом из проблемы является использование правил расширен-
ной совместимости типов Borland Pascal для объектов и разработка
прикладных программ с использованием полиморфических методов. Ес-
ли процедура DragIt инструментального средства установлена так,
что может работать с полиморфическими объектами, то она будет ра-
ботать с любыми объектами, определенными в инструментальном
средстве, и с любыми дочерними объектами, которые вы определите
сами. Если типы объектов инструментального средства используют
виртуальные методы, то объекты и программы инструментального
средства могут работать со сделанными вами графическими фигурами
в собственных терминах самих фигур. Определенный вами сегодня
виртуальный метод может вызываться файлом модуля (.TPU, .TPW или
. TPP) инструментального средства, который был написан и оттранс-
лирован год назад. Объектно-ориентированное программирование дает
такую возможность, а виртуальные методы являются ключом к ней.
Понимание того, как виртуальные методы делают возможными та-
кие вызовы полиморфических методов требует пояснения описания и
использования виртуальных методов.