Метод становится виртуальным, если после его заголовка стоит служебное слово Virtual. Необходимо помнить, что если метод в родительском типе объявлен как виртуальный, то все одноименные методы у потомков так же должны быть виртуальными. Кроме того, они все должны иметь одинаковый набор формальных параметров, что и самый первый виртуальный метод.
Если объекты являются динамическими, то, по аналогии с динамическими переменными они должны создаваться и уничтожаться. Для этого введены понятия «Конструктор» и «Деструктор», которые обсуждаются далее. Так, типы Point и Circle можно определить следующим образом:
Type
Point = object
…
Constructor Create (a, b: integer);
Destructor Done; VIRTUAL;
Procedure SwitchOn; VIRTUAL;
Procedure SwitchOff; VIRTUAL;
Procedure Move (dx, dy: integer);
end;
Circle = object (Point)
…
Constructor Create (a, b, R: integer);
Procedure SwitchOn; VIRTUAL;
Procedure SwitchOff; VIRTUAL;
end;
Полные описания методов остаются такими же, как и раньше. Теперь обращения к методам
OnePoint.Move (10, -20);
OneCircle.Move (10, -20);
дадут разный результат, то есть определение виртуального метода можно представить как шаблон для всех родственных ему методов.
Свойство полиморфизма предоставляет очень широкие возможности при разработке программ. Типы объектов и методы, определенные в различных модулях, могут поставляться пользователям в виде TPU-файлов без исходного кода. Для работы с объектами модулей только необходимо знать содержимое интерфейсной части. Зная его, можно создавать не только компактные описания новых объектов, но и добавлять новые методы к уже существующим. Возможность добавления новых функциональных характеристик в программу без модификации ее исходного текста называется способностью к расширению. С другой стороны, работа с виртуальными методами происходит немного медленнее и требует дополнительных затрат памяти, но это не должно служить препятствием к широкому использованию виртуальных методов.
Конструкторы и деструкторы
Корректная работа с виртуальными методами требует определенных правил.
Если объектный тип содержит хотя бы один виртуальный метод, то он должен иметь хотя бы один особый метод, называемый конструктором (этот метод может быть и унаследован). Конструктор должен быть применен к экземпляру объекта до первого вызова виртуального метода так же, как перед обращением к динамической переменной необходимо ее создать. Кроме этого, каждый экземпляр объекта должен инициализироваться отдельным вызовом конструктора. Другие экземпляры, даже если они содержат правильные данные, но не проинициализированы, приведут к ошибке выполнения при любых вызовах их виртуальных методов. Например:
Var
OnePoint, TwoPoint: Point;
Begin
OnePoint.Create (50,100);
…
TwoPoint.Move (21, -20); { Неправильный вызов, второй экземпляр не создан }
Каждый тип объекта, содержащий виртуальные методы, имеет таблицу виртуальных методов (ТВМ), хранящуюся в области данных. ТВМ содержит размер типа объекта и для каждого виртуального метода указатель кода, исполняющий данный метод. Конструктор устанавливает связь между вызывающим его экземпляром объекта и его ТВМ.
Так как имеется только одна ТВМ для любого типа объекта, то отдельные экземпляры объекта содержат только адрес ТВМ, а конструктор устанавливает значение этого адреса.
С процедурой освобождения памяти связан особый вид метода, называемый деструктором, и предназначенный для выполнения действий завершающего характера. В отличие от методов-конструкторов, деструкторы могут быть виртуальными и могут наследоваться, в одном объектном типе может быть определено несколько деструкторов.
В случае единственного деструктора в Турбо Паскале рекомендуется использовать название Done. Этот метод должен инкапсулировать все детали очистки своего и вложенных объектов и структур данных. Основное преимущество использования деструктора заключается в удалении из памяти полиморфных объектов, то есть таких, которые были созданы во время вызова метода, а не во время компиляции.
Так как размеры типов объектов различны, то во время компиляции из полиморфного объекта нельзя извлечь какую-либо информацию о его размере. Эта информация становится доступной для деструктора в момент удаления при обращении к таблице виртуальных методов экземпляров объектов этого типа.
Сам по себе метод деструктора может быть пустым и выполнять только функцию связи с процедурой высвобождения памяти:
Destructor Point.Done;
Begin
End;
Деструктор дочернего типа последним действием должен вызывать соответствующий деструктор своего непосредственного предка, чтобы освободить поля всех наследуемых указателей объекта. В Турбо Паскале можно использовать служебное слово INHERITED (V7.0), с помощью которого можно вызывать методы предка без указания его имени, например:
Destructor Circle.Done;
Begin
INHERITED Done;
End;
§10.4. Динамические объекты
Все экземпляры объектных типов, так же, как и значения любых других типов, могут быть представлены в программе либо посредством описаний с использованием служебного слова Var, либо динамически, что используется гораздо чаще. Если динамический объект содержит виртуальные методы, то он должен инициализироваться с помощью вызова конструктора, например следующим образом:
Var
OneP: ^Point;
…
New (OneP);
OneP^.Create (50, 100);
x1 := OneP^.CetX;
…
Затем вызовы методов могут происходить обычным образом с использованием указателя. Турбо Паскаль допускает использование расширенной процедуры New, совмещающей создание объекта и его инициализацию, которая имеет два параметра: имя указателя и имя конструктора:
New (OneP, Create(50,100));
Здесь вызов конструктора не содержит составного имени, так как первый параметр однозначно определяет, из какого объектного типа берется конструктор.
Аналогично для освобождения памяти при позднем связывании используется процедура Dispose с расширенным синтаксисом:
Dispose (OneP, Done);
Самостоятельный вызов деструктора вне процедуры Dispose не приведет к освобождению памяти, занимаемой экземпляром объекта.
Скрытые поля и методы
Часть полей и методов объектных типов можно объявить как скрытые. Смысл введения таких компонент заключается в ограничении области видимости их имен, так же, как и в модулях. Для этих целей в Турбо Паскале дополнительно введены два служебных слова PRIVATE и PUBLIC. В итоге описание объекта в полной форме выглядит следующим образом:
Type
NewObject = OBJECT (<родитель>);
<поля>; { общедоступные }
<методы>; { общедоступные }
PRIVATE
<поля>; { скрытые }
<методы>; { скрытые }
PUBLIC
<поля>; { общедоступные }
<методы>; { общедоступные }
End;
Объекты наиболее сильно подвергаются изменениям от версии к версии, поэтому в Delphi использование объектов несколько отличается от использования в Турбо Паскале 7.0.
Контрольные вопросы -
Назовите первые объектно-ориентированные языки программирования.
-
Какую структуру имеет классификация различных объектов?
-
Как называется более низкий уровень иерархии относительно текущего?
-
Как называется более высокий уровень иерархии относительно текущего?
-
Поясните понятие «иерархия объекта».
-
Поясните понятие «методы объекта».
-
Какое служебное слово используется для описания структуры «объект»?
-
Поясните понятие «инкапсуляция».
-
Поясните понятие «наследование».
-
Поясните понятие «полиморфизм».
-
Поясните понятие «раннее связывание».
-
Поясните понятие «позднее связывание».
-
Как сделать метод виртуальным?
-
Поясните понятие «конструктор» в применении к объектам.
-
Поясните понятие «деструктор» в применении к объектам.
-
Поясните понятие «скрытые поля и методы».
Литература -
Зелковиц М., Шоу А., Гэннон Дж. Принципы разработки программного обеспечения. Пер. с англ. М.: Мир, 1982 – 368 с., ил.
-
Одинцов И.О. Профессиональное программирование. Системный подход. – 2-е изд. перераб. и доп. – СПб.: БХВ-Петербург, 2004. – 624 с.: ил.
-
Давыдов В.Г. Программирование и основы алгоритмизации: Учеб. Пособие. – М.: Высш. шк., 2003. – 447 с.: ил.
-
Кнут Д. Искусство программирования для ЭВМ. т.1. Основные алгоритмы. – М.: Мир, 1975. – 736 с., ил.
-
Белов В.С., Бруттан Ю.В., Мотайленко Л.В. и др. Основы информатики и информационных технологий. Часть 1. Основы информатики. Пособие для поступающих в вуз. Под общ. ред. к.т.н., доцента В.С. Белова, — СПб/Псков, Изд-во СПбГПУ, 2004 — 160 с.
-
Единая система программной документации. ГОСТ 19.701-90. Схемы алгоритмов, программ, данных и систем. Условные обозначения и правила выполнения.
-
Единая система программной документации. ГОСТ 19.002-80. Схемы алгоритмов и программ. Правила выполнения.
-
Единая система программной документации. ГОСТ 19.003-80. Схемы алгоритмов и программ. Обозначения условные графические.
-
Турбо Паскаль 7.0. Самоучитель. – СПб.: Питер; К.: Издательская группа BHV, 2002. – 416 с.: ил.
-
Немюгин С.А. TURBO PASCAL – СПб, 2000.
-
Фаронов В.В. Турбо Паскаль 7.0. Начальный курс. Учебное пособие. – М.: «Нолидж», 1999. – 616 с., ил.
-
Федоренко Ю. Алгоритмы и программы на Turbo Pascal. Учеб. Курс. – СПб.: Питер, 2001.
-
Зуев Е.А. Язык программирования Turbo Pascal 6.0, 7.0. – М.: Веста, Радио и связь, 1993.
-
Климова Л.М. PASCAL 7.0: Практическое программирование. Решение типовых задач.: Учебное пособие. – М.,: 2000.
Полетаев Игорь Алексеевич
Полетаев Дмитрий Игоревич
Полетаева Ольга Александровна
Программирование на языке высокого уровня Паскаль
Учебное пособие
Для студентов технических специальностей всех форм обучения
Технический редактор: Полетаев И.А.
Компьютерная верстка: Полетаев И.А
Напечатано с готового оригинал-макета,
предоставленного авторами
________________________________________________________________
Подписано в печать _______________ Формат 60х90/16.
Гарнитура «Bookman Old Style». Усл. печ. л. 9,5
Тираж ________ экз. Заказ № ______
Адрес издательства:
Россия, 180000, Псков, ул. Л.Толстого, 4
Издательство ППИ
Достарыңызбен бөлісу: |