- •Содержание
- •Часть 1. Основные понятия программирования §1.1. Этапы разработки программного обеспечения
- •§1.2. Основные сведения об алгоритмах Понятие алгоритма
- •Свойства алгоритма
- •Формы записи алгоритмов
- •Блок-схемы алгоритмов
- •§1.3. Языки программирования
- •§1.4. Паскаль и Object Pascal, Турбо-Паскаль и Delphi
- •Контрольные вопросы
- •Язык, оболочка и интегрированная среда разработки
- •Часть 2. Общие сведения о языке Паскаль §2.1. Алфавит и служебные слова
- •Описание общих конструкций языка
- •§2.2. Структура программы
- •§2.3. Разделы описаний Описание меток
- •Определение констант
- •Определение типов
- •Описание переменных
- •Контрольные вопросы
- •Часть 3. Простые типы данных Иерархия типов
- •§3.1. Целые типы
- •§3.2. Вещественные типы
- •§3.3. Логический тип
- •§3.4. Литерный тип
- •§3.5. Перечисляемый тип
- •§3.6. Диапазоны (интервальный тип)
- •Дополнительные типы в Delphi
- •Контрольные вопросы
- •Глава 4. Операторы языка Паскаль Выражения
- •§4.1. Оператор присваивания
- •§4.2. Ввод-вывод данных
- •§4.3. Составной оператор
- •§4.4. Пустой оператор
- •§4.5. Безусловный оператор перехода
- •§4.6. Условный оператор
- •§4.7. Оператор цикла с параметром for
- •§4.8. Оператор цикла с предусловием while
- •§4.9. Оператор цикла с постусловием repeat
- •§4.10. Оператор выбора case
- •Контрольные вопросы
- •Глава 5. Процедурное программирование §5.1. Функции
- •Параметры – значения
- •Параметры – переменные
- •Бестиповые параметры
- •§5.2. Процедуры
- •Правила использования подпрограмм
- •Рекурсия
- •Директивы
- •Процедурные типы
- •Пример использования подпрограмм
- •Контрольные вопросы
- •Глава 6. Структурированные типы данных
- •§6.1. Массивы
- •§6.2. Строки
- •§6.3. Записи
- •§6.4. Множества
- •Пример использования множеств
- •§6.5. Файлы
- •Установочные и завершающие операции
- •Операции ввода-вывода
- •Перемещения по файлу
- •Пример работы с файлом
- •Обработка ошибок ввода-вывода
- •Специальные операции
- •Пример объединения двух файлов
- •Текстовые файлы
- •Стандартные текстовые файлы
- •Файлы без типа
- •Контрольные вопросы
- •Глава 7. Динамические структуры данных §7.1. Динамические переменные
- •§7.2. Указатели
- •Работа с динамическими переменными
- •Пример двухсвязанного циклического списка
- •Указатели без типа
- •Контрольные вопросы
- •Глава 8. Низкоуровневые возможности Паскаля §8.1. Язык Ассемблер
- •§8.2. Доступ к аппаратуре Доступ к памяти
- •Доступ к портам ввода-вывода
- •Работа по прерываниям
- •Контрольные вопросы
- •Глава 9. Модули §9.1. Основные понятия
- •§9.2. Использование модулей
- •§9.3. Стандартные модули
- •§9.4. Модуль Crt
- •Работа с экраном в текстовом режиме
- •Работа с клавиатурой
- •Работа со звуком
- •§9.5. Модуль dos
- •§9.6. Графический режим монитора
- •Контрольные вопросы
- •Глава 10. Введение в объектно-ориентированное программирование §10.1. История развития программирования
- •Понятие объекта
- •§10.2. Свойства объектов
- •Раннее и позднее связывание
- •§10.3. Виртуальные методы
- •Конструкторы и деструкторы
- •§10.4. Динамические объекты
- •Скрытые поля и методы
- •Контрольные вопросы
- •Литература
Раннее и позднее связывание
Рассмотрим объектные типы Point и Circle. Они связаны отношением наследования и содержат, наряду с другими, методы SwitchOn, SwithOff и Move. Первые два из них реализуют алгоритмы рисования и удаления фигуры с экрана, они существенно различны для разных типов. Алгоритм же метода Move практически одинаков для обоих типов: удаление фигуры со старого места, изменение ее координат и рисование на новом месте. Например:
Procedure Move (dx, dy: integer);
Begin
SwitchOff;
X:=X+dx;
Y:=Y+dy;
SwitchOn;
end;
Рассмотрим вариант унаследования этого метода без переопределения. Пусть имеются экземпляры двух разных объектов:
Var
OnePoint: Point;
OneCircle: Circle;
то вызовы методов
OnePoint.Move (10, -20);
OneCircle.Move (10, -20);
приведут к одному и тому же действию: перемещению точки. Это связано с тем, что экземпляр типа-потомка вызывает унаследованный метод Move, который жестко связан с методами Point.SwitchOn и Point.SwitchOff на ранней стадии, то есть еще во время компиляции программы. В данном случае связь методов является статической.
Для того, чтобы в полной мере использовать свойство полиморфизма и использовать одни и те же унаследованные методы, по разному применяемые к разным объектам, необходимо, во-первых, разорвать связь метода Move с методами предка Point, во-вторых, обеспечить возможность вызывать разные методы SwitchOn и SwitchOff в зависимости от того, какой объект вызывает Move.
Это можно реализовать только во время вызова метода, то есть в процессе выполнения программы, поэтому такой механизм называется динамическим или поздним связыванием и достигается введением виртуальных методов.
§10.3. Виртуальные методы
Метод становится виртуальным, если после его заголовка стоит служебное слово 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-файлов без исходного кода. Для работы с объектами модулей только необходимо знать содержимое интерфейсной части. Зная его, можно создавать не только компактные описания новых объектов, но и добавлять новые методы к уже существующим. Возможность добавления новых функциональных характеристик в программу без модификации ее исходного текста называется способностью к расширению. С другой стороны, работа с виртуальными методами происходит немного медленнее и требует дополнительных затрат памяти, но это не должно служить препятствием к широкому использованию виртуальных методов.
