Модули и объекты в языке Турбо Паскаль 7.0
кции называются методами. Как видим, каждая точка
характеризуется некоторым набором данных (своими координатами X и У, цветом
COLOR и признаком светимости VISIBLE). Над этими данными определены все
необходимые алгоритмические действия. С помощью этих переменных можно
осуществлять все предусмотренные, в объекте действия, например, для
переменных типа TPOINT можно высветить или погасим, любую точку,
переместить ее по экрану, изменить цвет.
Нетрудно заметить, что описание объекта и использование объектных
переменных во многом похоже на описание и использование записей:
инкапсулированные в объекте данные и методы становятся доступны с помощью
оператора присоединения WITH или с помощью составных
имен, например:
if Point.GetVisible then Polnt.SetVisible(False);
При описании объекта вначале, описываются все инкапсулированные в
нем данные, а затем - методы доступа к этим данным. В качестве методов
используются процедуры и функции, а также конструкторы и деструкторы.
Таким образом, указание методов при описании объекта подобно их
опережающему описанию. Поскольку данные и методы инкапсулированы в одном
объекте, все данные автоматически становятся глобальными, по отношению к
любым методам и могут использоваться в них произвольным образом. Точнее
говоря, любой метод объекта работает с невидимым оператором WITH,
обеспечивающим ему доступ ко всем полям (как мы увидим далее, поля могут
следовать в объявлении типа и после объявления метода и в этом смысле не
являться для него глобальными). При обращении к методу ему передается
особый идентификатор SELF, представляющий собой обобщенное имя экземпляра
объекта. Любой метод может использовать идентификатор SELF, чтобы явно
указать на принадлежащий объекту метод или поле. Например:
type ТСоо = record
X.Y: integer;
end;
TPoint = object
X,Y: integer;
Procedure lnit(Coo: TCoo);
end;
Procedure TPofntfCoo: TCoo):
begin
with Coo do
begin
Self.X := X;
Self.Y := Y;
end;
end;
2.3 Наследование
Любой объект может быть объявлен потомком ранее описанного объекта.
В этом случае он наследует все данные и методы объекта-родителя и может
дополнять их своими данными и методами. При объявлении объекта-потомка за
словом OBJECT в круглых скобках указывается имя объекта-родителя. У объекта
может быть сколько угодно потомков, но только один родитель. При объявлении
объекта-потомка TUNE перечислены лишь те данные и методы, которых недостает
в объекте-родителе TPOINT, остальные TLINE автоматически наследует от
своего родителя.
Таким образом, описание объекта-потомка TLINE эквивалентно такому
описанию объекта TLINE_ANOTHER:
type
TLine_Another = object
X, Y Integer; {Координаты начала линии}
Color word; {Цвет линии)
Visible Boolean; (Признак светимости)
XE.YE: Integer; {Координаты второго конца)
Procedure SetLocation(NewX, NewY: integer);
{Задает новое положение начала линии)
Procedure SetColor(NewColor: word);
{Устанавливает цвет линии)
Procedure SetVIsible(Vis: Boolean);
{Выводит или гасит линию}
Procedure GetLocation(var XLoc, YLoc: integer);
{Возвращает координаты начала линии}
Function GetColor: word;
{возвращает цвет линии}
Function GetVisible: Boolean;
{Возвращает признак светимости линии}
Procedure SetLIneLocationfxl.X1,Y1,x2 ,y2: integer);
{Задает новое положение линии на экране}
Procedure GetLineLocatlon(var x11,y1l,x2l,y2l):integer);
{Возвращает координаты линии}
Procedure SetLineVJsible(vis: Boolean);
{Выводит или гасит линию)}
end; {Конец описания объекта TLIne_Another}
Из этого примера видно главное преимущество наследования: при
описании объекта-потомка вам нет необходимости заново описывать уж
существующие в объекте-родителе поля и методы. Потомок просто использует
их нужным образом для реализации требуемых от него действий все, в чем
нуждается потомок, ( это описать специфичные для него поля методы,
недостающие в объекте-родителе.
Наследование распространяется на любые объекты, в том числе и
объекты-потомки: если в качестве родителя указано имя объекта, который сам
по себе является потомком, новый объект наследует все свойства своего
родителя и все свойства своих прародителей. Таким образом, наследование
обеспечивает создание дерева родственных объектов.
Как и любое другое дерево, дерево объектов имеет «корень» ( объект
являющийся прародителем всех других объектов иерархии, и «ветви»
порожденные от него потомки. По мере передвижения от корня к ветвям и
перехода с ветви на ветвь объекты разрастаются в своих размерах,
присоединяя к себе все новые и новые поля и методы. Если иерархия объектов
хорошо продумана, на каждом ее уровне к объекту-родителю добавляются только
необходимые поля и методы, поэтому в таком разрастании на самом деле нет
ничего плохого. Более того, компоновщик Турбо Паскаля тщательно проверит
откомпилированную программу и удалит из нее все лишнее - в том числе в
исполняемую программу (ЕХЕ-файл) не будут включены методы, которые по каким-
либо причинам не используются в программе.
Механизм наследования ( это, пожалуй, самое мощное свойство ООП. Без
наследования объекты превращаются в простую комбинацию данных и
подпрограмм, не дающую качественных преимуществ по сравнению с
традиционными для Паскаля процедурами и модулями. Наоборот, механизм
наследования позволяет строить библиотеку по принципу «от простого - к
сложному». Вводя с помощью наследования новый объект в свою библиотеку,
программист в максимальной степени использует уже созданные (и, возможно,
отлаженные) ранее объекты. Такой принцип конструирования программ
называется восходящим программированием. В отличие от нисходящего
программирования, он не дает возможности поэтапного создания программы.
Мелкие детали реализации объектов заслоняют собою генеральный алгоритм,
поэтому при использовании ООП рекомендуется сочетание подходов: методами
нисходящего программирования генеральный алгоритм расчленяется на ряд
относительно крупных и законченных в смысловом отношении фрагментов
(модулей), а реализация этих фрагментов может основываться на объектно-
ориентированном программировании.
2.4 Полиморфизм
Объект-потомок может не только дополнять поля и методы родителя, но
и заменять методы родителя на новые (заменять поля родителя нельзя!).
Например, вместо правила SETLINEVISIBLE мы могли бы в объекте TLINE
объявить правило SETVISIBLE, которое в этом случае перекроет (заменит
собой) одноименное правило объекта-родителя TPOINT. В результате, к разным
родственным объектам TPOINT и TUNE можно было бы применять одноименные
правила SETVISIBLE, обеспечивающие сходные в смысловом отношении действия -
показать или сделать невидимым графический объект. Свойства, позволяющее
называть разные алгоритмические действия одним именем, называется
полиморфизмом.
В Турбо Паскале существует возможность связывания данных с методами
на этапе исполнения программы - такое связывание называется поздним. При
позднем связывании в описании объекта соответствующий метод дополняется
стандартной директивой VIRTUAL. Такие методы называются виртуальными. В
отличие от этого методы, с которыми осуществлено раннее связывание (на
этапе компиляции), называются статическими.
Появление директивы VIRTUAL в объявлении метода как бы предупреждает
компилятор: «Пока ты не знаешь, что я хочу. Придет время -запроси
образец!». Встретившись с таким объявлением, компилятор не будет
устанавливать связь объекта с методом. Вместо этого он создаст специальную
таблицу, которая называется таблицей виртуальных методов (ТВМ). В этой
таблице хранятся адреса точек входа всех виртуальных методов. Для каждого
типа объекта создается своя ТВМ и каждый экземпляр объекта пользуется этой
единственной для объектов данного типа таблицей. ТВМ обеспечивает
работающую программу механизмом связывания объекта с полями. Фактическое
связывание осуществляется с помощью обращения к конструктору - специальному
методу, который во всем подобен обычной процедуре, но в заголовке вместо
PROCEDURE содержит зарезервированное слово CONSTRUCTOR. В момент обращения
к конструктору в специальное поле объекта заносится адрес нужной ТВМ, в
результате чего все виртуальные методы (в том числе и унаследованные от
родителей!) получают доступ к нужным полям.
Конструктор может не обращаться к виртуальному методу и даже вообще
быть пустым, т.е. не иметь никаких исполняемых операторов (как в нашем
примере), тем не менее, объект будет инициализирован правильно. Дело в том,
что заголовок CONSTRUCTOR предписывает компилятору создать специальный
набор машинных инструкций, который инициализирует ТВМ и исполняется в
момент обращения к конструктору до выполнения его (конструктора)
содержательной части. В объекте может быть сколько угодно конструкторов, но
ни один из них не может быть виртуальным.
Выбор того, каким именно - статическим или виртуальным - должен быть
метод, зависит от специфики задачи и Ваших вкусо
| | скачать работу |
Модули и объекты в языке Турбо Паскаль 7.0 |