TURBO PASCAL

Новости

Программы   

Turbo Pascal 

Игры

Документация   

Странности

FAQ

Ссылки

Форум

Гостевая книга

Рассылка

Благодарности

Об авторе

 

 

Полиморфические объекты 

             При чтении  предыдущего  раздела вы,  возможно,  задали себе
        вопрос: "Если любой порожденный от типа параметра тип может пере-
        даваться  в качестве параметра,  то как же пользователь параметра
        узнает,  какой тип объекта он получил?" Фактически,  пользователь
        явно  этого и не знает.  Точный тип фактического параметра не из-
        вестен во время компиляции.  Фактический параметр может быть объ-
        ектом любого дочернего от параметра-переменной типа, и именно по-
        этому он называется полиморфическим объектом.

             Теперь, чем же именно хорош полиморфический  объект?  Прежде
        всего полиморфические объекты позволяют обрабатывать объекты, чей
        тип неизвестен на момент компиляции. Это общее замечание настоль-
        ко  ново для образа мышления Паскаля,  что пример для вас не поя-
        вится незамедлительно. (Со временем вы будете удивлены, насколько
        естественно это выглядит. То есть, когда вы действительно станете
        объектно-ориентированным программистом.)

             Предположим, что вы написали инструментальное  средство  для
        вычерчивания графиков,  поддерживающее многочисленные типы фигур:
        точки,  окружности, квадраты, прямоугольники, кривые и т.д. В ка-
        честве  части этого инструментального средства вы хотите написать
        программу,  которая будет перемещать графическую фигуру по экрану
        с помощью устройства типа "мышь".

             При старом способе необходимо было написать отдельную проце-
        дуру перемещения для каждого типа графической фигуры, поддержива-
        емой  инструментальным  средством.  Вы  должны  были  бы написать
        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) инструментального средства, который был написан и оттранс-
        лирован год назад. Объектно-ориентированное программирование дает
        такую возможность, а виртуальные методы являются ключом к ней.

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

Содержание

На первую страницу

Rambler's Top100 Rambler's Top100
PROext: Top 1000

(с)Все права защищены

По всем интересующим вопросам прошу писать на электронный адрес

Hosted by uCoz