ОСНОВЫ ОБЪЕКТНОГО ПРОГРАММИРОВАНИЯ В СИСТЕМЕ ТУРБО-ПАСКАЛЬ
Объект в ТурбоПаскале - это структура данных, содержащая поля данных различных типов и заголовки методов и обобщающая структуру «Запись» (record).
Синтаксис описания объекта:
<ИмяПотомка>=
оbjесt<ИмяПредка> поле;
поле;
…
метод;
…
метод;
end;
В отличие от записи полями объекта могут быть, кроме данных, еще и методы, обрабатывающие эти данные
Метод - это процедура или функция, объявленные внутри описания объекта. Синтаксис описания метода:
procedure <Заголовок>(<Параметр1>, <Параметр2>:integer),
Метод имеет доступ к полям данных объекта, не требуя передачи их ему в виде параметров
Объявление метода внутри объявления объектного типа содержит только заголовок. Тело метода определяется вне объявления объекта. Его заголовок должен содержать имя объекта, которому принадлежит метод. Например:
procedure <ТипОбъекта.Метод>
(<Параметр1>, <Параметр2> : integer);
begin
…
…
еnd;{Метод}
Методы подразделяют на статические и виртуальные. Виртуальный метод отличается от статического тем. что реализующий его код подсоединяется к исполняемой программе не в процессе компиляции, а в процессе выполнения, что достигается, так называемым, поздним связыванием. Это дает возможность строить иерархию объектов с одинаковыми названиями методов, реализуемыми, однако, различными кодами.
Синтаксис виртуального метода:
procedure <Метод> (<Параметр1>, <Параметр2> : integer): virtual;
Кроме обычных процедур и функций, ТурбоПаскаль 6.0 реализует два специальных типа методов: конструктор и деструктор.
Конструктор - это специальный метод, инициализирующий объект, содержащий виртуальные методы, он объявляется специально зарезервированным словом constructor. Конструктор инициализирует объект путем установления связи между объектом и специальной таблицей виртуальных методов, содержащей адреса кодов, реализующих виртуальные методы. Конструктор может также использоваться для инициализации полей данных объекта.
Деструктор - это специальный метод, освобождающий память «кучи» от динамических объектов. Он объявляется с использованием специально зарезервированного слова destructor.
Основными отличительными свойствами объекта являются
• инкапсуляция - объединение записей с процедурами и функциями, работающими с этими записями;
• наследование - задание объекта, затем использование его для построения иерархии порожденных объектов с наследованием доступа каждого из порожденных объектов к коду и данным предка;
• полиморфизм - задание одного имени действию, которое передается вверх и вниз по иерархии объектов с реализацией этого действия способом, соответствующим каждому объекту в иерархии.
Рассмотрим смысл каждого из перечисленных свойств на примере построения на экране дисплея точек разных цветов (звездного неба).
Инкапсуляция.
Основой решения задачи является задание положения (позиции) отдельной точки на экране, описываемого координатами Х и Y. Для задания координат подходит тип «запись»:
Pozition = record
X, Y : integer;
end;
Далее может быть необходимо задать значения координат (такая процедура носит название инициализации). Создадим соответствующую процедуру:
procedure Init(CoordX, CoordY : integer);
begin
X : =
CoordX;
Y : = CoordY;
end;
Затем потребуется знание фактических значений координат. Для этого вводим две функции:
function GetX : integer;
begin
GetX: = X;
end;
function GetY: integer;
begin
GetY: = Y;
end;
По нашему замыслу процедура Init и функции GetX и GetY должны работать только с полями записи Pozition.
Введение объектов позволяет зафиксировать это положение, объявив и поля, и действия над ними в единой конструкции:
Pozition = object
X, Y: integer;
procedure Init(CoordX, CoordY : integer);
function GetX : integer;
function GetY : integer;
end;
Процедура Init и функции GetX и GetY являются методами объекта Pozition.
Для инициализации экземпляра типа Pozition достаточно вызвать его метод, как если бы он был полем записи:
var
FirstPozition : Pozition;
…
FirstPozition.Init(10,15);
Метод задается так же, как и процедура в модуле: внутри объекта записывается заголовок (как в секции Interface модуля); при этом все поля, используемые мето-дом, должны предшествовать его объявлению. Определение метода (расшифровка действий) происходит вне объявления объекта. Имя метода должно предваряться названием типа объекта, которому метод принадлежит, сопровождаемым точкой. Например,
procedure Pozition. Init(CoordX, CoordY: integer);
begin
X: = CoordX:
Y: = CoordY;
end;
Заметим, что имена формальных параметров метода не могут совпадать с именами полей данных объекта.
Также как модуль скрывает детали реализации процедур от пользователя, объект может скрывать свои поля и методы. Для этого используется ключевое слово private (личный). Личные поля и методы доступны только внутри метода. Объявление выглядит следующим образом:
type
ObjectName=object
поле;
…
поле;
метод;
метод;
private
поле;
…
поле;
метод;
…
метод;
end;
Наследование. Рассмотрим точку с координатами Х и Y. Ее можно сделать видимой или невидимой, ей можно задать цвет, ее можно переместить. Создадим объект с такими возможностями:
Point=object
X,Y : integer; "
procedure Init(CoordX, CoordY : integer);
function GetX : integer;
function GetY . integer;
Visible: Boolean;
Color: Word;
procedure Init(CoordX, CoordY : integer; InitCoIor : Word);
function Is Visible : Boolean;
procedure Show;{показывает точку}
procedure Blind; {стирает точку}
procedure Jump(NextX, NextY : integer);{nepeMeiuaer точку}
end;
Заметим, однако, что поля X.Y и методы GetX, GetY практически совпадают с соответствующими полями и методами объекта Pozition.
Турбо-Паскаль предоставляет возможность учесть эту ситуацию. Следует считать тип объекта Point порожденным типом Pozition, записав это следующим образом:
Point=object(Pozition)
Visible : Boolean;
Color : Word;
procedure Init(CoordX, CoordY : integer; InitColor : Word);
function Is Visible . Boolean;
procedure Show;
procedure Blind:
procedure Jump(NextX, NextY : integer);
end;
Объект Point теперь наследует свойства объекта Pozition. Поля X,Y явно не заданы в Point, но Point ими обладает благодаря наследованию, т.е. можно написать
Point.X:=17;
Смысл объектно-ориентированного программирования заключается в работе с полями объекта через его методы.
Полиморфизм. Предположим, надо создать объект «кружок». Очевидно, что новый объект должен иметь предком объект Point, обладая всеми его свойствами, кроме того. быть больше по размеру. Однако, ясно, что «высветить» точку и закрашенную окружность не удастся одними и теми же командами. Турбо-Паскаль разрешает сохранить потомку имя родительского метода, «перекрывая» его. Чтобы перекрыть родительский метод, надо просто задать его с тем же именем, но с другим телом (кодом) и, если необходимо, с другим набором параметров. Такой метод делается виртуальным и к его объявлению добавляется слово virtual. Применение виртуальных методов налагает ограничения на процедуры инициализации, которые должны записываться с зарезервированным словом constructor и иметь общее имя Init
Каждый отдельный экземпляр объекта должен инициализироваться с помощью отдельного вызова конструктора
Для очистки и удаления динамически распределенных объектов существует специальная процедура destructorDone.
Деструктор комбинирует шаг освобождения памяти в «куче» с некоторыми другими задачами. Метод деструктора может быть пустыу), поскольку работу выполняет не только код тела, но и код, генерируемый Турбо-Паскалем в ответ на зарезервированное слово destructor.