Раннее и позднее связывание методов

I. Основные принципы ООП

1. Инкапсуляция– принцип ООП, который заключается в объединении в единое целое данных и алгоритмов их обработки.

Данные объектав ООП называются полями объекта, а алгоритмы, т. е. действия над данными объекта,называются методами объекта, которые оформляются в виде подпрограмм.

2. Наследование– принцип ООП, который заключается в свойстве объектов порождать своих потомков.

Объект-потомок автоматически наследует от родителя все поля и методы, может дополнять объекты новыми полями и заменять или дополнять методы родителя.

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

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

II. Структура объявления объектного типа

TYPE

=OBJECT

:;

;

END;

После определения типа объекта должны следовать описания всех методов, перечисленных в объектном типе, которые представляют собой тексты процедур и функций. Отличие от обычного описания заключается в том, что имя подпрограммы, являющейся методом объекта, указываемое в её заголовке, состоит из 2 частей:

.

III. Свойство наследования

Каждый новый объектный тип может строиться на основе ранее определенного типа, называемого родительским типом, от которого наследуются все поля и методы. Для того, чтобы произошло наследование, в определение объектного типа после OBJECT в скобках необходимо указать имя родительского типа.

Правила наследования.

1. В определении типа наследника не должно быть полей, совпадающих по именам с полями родителя; имена методов у наследников и родителя могут совпадать – в этом проявляется свойство полиморфизма.

2. При построении объектного типа наследника, в первую очередь, наследуются поля родителя, затем добавляются поля наследника; после полей наследуются все методы родителя, затем добавляются методы наследника, если их имена не совпадают с именами методов родителя; если совпадения существуют, то это означает, что методы наследника являются полиморфными методами и замещают одноименные методы предка.

Свойство полиморфизма.

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

Правила наследования при полиморфизме:

· одноименные методы наследника заменяют методы родителя;

· методы наследника, не совпадающие по именам с методами родителя, добавляются после методов родителя.

IV. Виртуальные методы

Раннее и позднее связывание методов.

Методы объекта являются статическими методами, если компилятор размещает их и разрешает все ссылки на них во время компиляции и компоновки. Процесс, с помощью которого вызовы статических методов однозначно разрешаются компилятором во время компиляции, называется ранним связыванием.

При позднем связываниивызывающий и вызываемый методы не могут быть связаны по адресам во время компиляции, поэтому включается механизм, позволяющий выполнить связывание в тот момент, когда вызов действительно произойдет, т. е. во время выполнения программы.

Виртуальные методы и таблица виртуальных методов (ТВМ).

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

Позднее связывание осуществляется с помощью таблиц виртуальных методов (ТВМ), которые строятся компилятором в сегменте данных программы для всех виртуальных методов, описанных в программе. ТВМ представляет собой таблицу адресов процедур, которые являются виртуальными методами. Для любого объекта, содержащего виртуальные методы, требуется, чтобы в памяти находился экземпляр таблицы виртуальных методов.Для каждого объектного типа строится только одна ТВМ. Указатель на таблицу виртуальных методов автоматически заносится в специальное поле, которое имеется в каждом экземпляре объектного типа при выполнении конструктора. Обращение к ТВМ через этот указатель происходит при каждом вызове виртуального метода.

Конструктор.

Во время выполнения программы до исполнения виртуальных методов любого объекта должен выполниться метод-конструктор для данного экземпляра объекта, в который компилятор вставляет действия по связи неразрешенных ссылок с ТВМ.

Конструктор– это специальный вид процедуры, которая выполняет установочную работу для обеспечения позднего связывания. Все типы объектов, имеющих виртуальные методы, должны содержать конструктор, который всегда вызывается до первого вызова виртуального метода. Вызов виртуального метода без предшествующего обращения к конструктору может вызвать блокировку системы.

Конструктором может быть только процедура, в заголовке которой вместо служебного слова PROCEDURE необходимо написать CONSTRUCTOR.

Конструктор не может быть виртуальным.

После выполнения метода-конструктора при вызове виртуальных методов их адреса определяются из ТВМ.

Деструктор.

Деструктор служит для очистки памяти и удаления динамически размещенного объекта. Обычно в деструкторе указываются завершающие действия с объектом. В заголовке деструктора служебное слово PROCEDURE заменяется на DESTRUCTOR Для одного и того же типа объекта можно определить несколько деструкторов. Деструкторы можно наследовать, они могут быть статическими или виртуальными.

V. Пример объектного типа

1. Постановка задачи: реализовать движение точки на экране.

2. Математическая модель: каждая точка на экране характеризуется координатами x, y и состоянием v –видима/невидима.

3. Объявление объектного типа точка:

type

POINT=object

X, Y: integer; {координаты}

V: boolean; {признак видимости: TRUE-видима; FALSE-невидима}

function GET_X: integer; { получение координаты Х }

function GET_Y: integer; { получение координаты Y }

function GET_V: boolean; { получение признака видимости }

procedure INIT(X0, Y0: integer); { задание координат }

procedure TURN_ON; { рисование точки – получение видимой точки }

procedure TURN_OFF; { стирание точки – получение невидимой точки}

procedure MOVE(XN, YN: integer); { перемещение точки }

end;

4. Определение методов объекта POINT:

function POINT.GET_X; { получение координаты Х }

begin

GET_X:=X;

end;

function POINT.GET_Y; { получение координаты Y }

begin

GET_Y:=Y;

end;

function POINT.GET_V; { получение признака видимости }

begin

GET_V:=V;

end;

procedure POINT.INIT; { задание координат }

begin

X:=X0;

Y:=Y0;

V:=false;

end;

procedure POINT.TURN_ON; { получение видимой точки }

begin

if not V then

begin

PutPixel(X,Y,GetColor); { GetColor возвращает текущий цвет }

V:=true;

end;

end;

procedure POINT.TURN_OFF; { получение невидимой точки – стирание точки }

begin

if V then

begin

PutPixel(X,Y,GetBkColor); { GetBkColor возвращает фоновый цвет }

V:=false;

end;

end;

procedure POINT.MOVE; { перемещение точки }

var

F: boolean;

begin

F:=V;

if F then

TURN_OFF;

X:=XN;

Y:=YN;

if F then

TURN_ON;

end;

Свойство наследования.

Кроме точки, можно задать другие объекты, описывающие геометрические фигуры, например, объект типа окружность, который определяется радиусом, координатой центра, признаком видимости, и с ним возможны такие же действия, как с точкой: получение видимой окружности; получение невидимой окружности; перемещение окружности (изменение координат центра). Чтобы этот объект привязать к координатной сетке экрана, необходимо определить объектный тип PLACE (место), который будет иметь данные, общие для всех геометрических фигур, – координаты привязки объекта к экрану X и Y:

type

PLACE=object

X, Y: integer;

procedure INIT(X0, Y0: integer);

function GET_X: integer;

function GET_Y: integer;

end;

{ далее следует описание методов }

Каждый новый объектный тип может строиться на основе ранее определенного типа, называемого родительским типом, от которого наследуются все поля и методы. Чтобы произошло наследование, в объявлении объектного типа после OBJECT в скобках указывается имя родительского типа.

Используя тип PLACE как родительский, можно определить объектный тип POINT таким образом:

type

POINT=object(PLACE)

V: boolean;

procedure INIT(X0, Y0: integer);

function GET_V:boolean;

procedure TURN_ON;

procedure TURN_OFF;

procedure MOVE(XN, YN: integer);

end;

{ далее следует описание методов }

6. Свойство полиморфизма заключается в том, что в объявлении типа наследника могут быть методы, одноименные с именами методов родителя.

Объявление типа окружность c использованием в качестве родителя типа POINT будет следующим:

type

CIRCL=object(POINT)

R: integer;

procedure INIT(X0, Y0, R0: integer); { задание окружности }

procedure TURN_ON; { получение видимой окружности }

procedure TURN_OFF; { получение невидимой окружности }

procedure MOVE(XN, YN: integer); { перемещение окружности}

function GET_R: integer; { получение радиуса }

end;

Определение методов с использованием наследования при полиморфизме:

procedure CIRCL.INIT;

begin

X:=X0; Y:=Y0;

R:=R0;

V:=false;

end;

procedure CIRCL.TURN_ON;

begin

V:=true;

CIRCLE(X,Y,R);

end;

procedure CIRCL.TURN_OFF;

var

C: byte;

begin

C:=GetColor;

SetColor(GetBkColor); { установка цвета рисования }

Circle(X,Y,R);

V:=false;

SetColor(C);

end;

procedure CIRCL.MOVE;

var

F: boolean;

begin

F:=V;

if F then

TURN_OFF;

X:=XN;

Y:=YN;

if F then

TURN_ON;

end;

function CIRCL.GET_R;

begin

GET_R:=R;

end;

В результате текст процедуры CIRCL.MOVE совпадает с текстом процедуры POINT.MOVE, но машинные коды у этих процедур будут разные; CIRCL.MOVE при своем исполнении обращается к адресам процедур CIRCL.TURN_ON и CIRCL.TURN_OFF, а процедура POINT.MOVE – к адресам процедур POINT.TURN_ON и POINT.TURN_OFF.

Раннее и позднее связывание методов.

Ранее рассмотренные статические методы компилятор размещает и разрешает все ссылки на них во время компиляции и компоновки (раннее связывание).

Для примера, описанного ранее, в объекте CIRCL можно наследовать метод MOVE у объекта POINT. Методы TURN_ON и TURN_OFF должны быть объявлены виртуальными, чтобы с ними произошло позднее связывание.

Компилятор оставляет после компиляции неразрешенными ссылки к тем методам, которые объявлены виртуальными. Для описанного ранее примера в методе MOVE неразрешенными ссылками будут адреса методов TURN_ON, TURN_OFF, т. е. процедура MOVE будет не готова к исполнению после компиляции, т. к. ее машинный код полностью не определен.

Во время выполнения программы до исполнения виртуальных методов любого объекта должен выполниться метод-конструктор для данного экземпляра объекта, в который компилятор вставляет действия по связи неразрешенных ссылок с ТВМ.

Объявления объектных типов PLACE, POINT и CIRCL с использованием конструктора и виртуальных методов:

type

PLACE=object

X,Y: integer;

constructor INIT(X0, Y0: integer);

function GET_X: integer;

function GET_Y: integer;

end;

POINT=object(PLACE)

V: boolean;

constructor INIT(X0, Y0: integer);

function GET_V: boolean;

procedure TURN_ON; virtual;

procedure TURN_OFF;virtual;

procedure MOVE(XN, YN: integer);

end;

CIRCL=object(POINT)

R: integer;

constructor INIT(X0, Y0, R0: integer);

function GET_R: integer;

procedure TURN_ON; virtual;

procedure TURN_OFF; virtual;

end;

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

Обращение к деструктору, как правило, указывается при освобождении памяти от динамического объекта при вызове процедуры DISPOSE:

DISPOSE (, );

Метод деструктора также может быть пустым:

DESTRUCTOR ;

BEGIN

END;

При этом компилятором генерируетсякод в ответ на зарезервированное слово DESTRUCTOR.


2676743795753465.html
2676805302384680.html
    PR.RU™