Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
31
Добавлен:
30.04.2013
Размер:
134.66 Кб
Скачать

15.3. Статические и динамические объекты

Чтобы создать объект, надо выполнить его конструктор.

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

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

  • Первый заключается в выполнении двух действий: вначале получить необходимую память для объекта, используя процедуру New, а затем выполнить конструктор Init (этот процесс изображен ниже для объекта PL1^).

  • Второй способ основывается на модифицированной процедуре New, которая имеет два параметра: первый – имя переменной – указателя на объект, а вторая – вызов конструктора.

Так, запись

New(PL2, Init(130,251,Red));

имеет следующий смысл: выделить для объекта память в динамической области, вернув указатель на нее в переменную PL2, и выполнить конструктор для этого объекта, установив его свойства следующими: координаты (x=130, y=251) и красный цвет.

Вместе с модифицированной процедурой New для обеспечния работы с объектами можно использовать и модифицированную процедуру освобождения памяти из динамической области Dispose, в которой также имеется два параметра. Покажем это на примере уничтожения объектаPL2:

Dispose(PL2, Done);

Эта запись означает следующее: уничтожить объект, на который указывает переменная PL2, и затем освободить занимаемую им память.

Иллюстрация сказанного приведена ниже.

Type

Ppoint=^TPoint; {тип – указатель на объект}

Var

L1: TPoint; {имена статических объектов}

PL1, PL2 : PPoint; {имена динамических объектов,

точнее – имена указателей на объекты,

которые будут созданы в динамической

области программы}

. . .

begin

L1.Init(10,20,Blue); {создать статический объект «точка»}

PL1:=New(PPoint); {запросить память под объект}

PL1^.Init(10,20,Blue);{и создать его}

New(PL2, Init(130,251,Red)); {второй вариант создания

динамического объекта, за счет модифицированной процедуры New}

. . .

L1.Show; {Показать на экране объект}

PL2^.Show; {Показать на экране объект}

PL2^.MoveTo(45,30); {Переместить объект на новое место}

. . .

Dispose(PL2, Done); {Уничтожить объект и освободить память}

. . .

Т

Type

PCircle = ^TCircle;

Tcircle = object (TPoint) {Класс типа Окружность}

Radius : integer; { радиус }

Constructor Init(ix,iy:integer; {кординаты}

iRadius:integer; {}

icolor: byte); {цвет}

procedure Show;virtual;

end;

PRect = ^TRect;

TRect = object(TPoint) { Класс типа Прямоугольник}

Width,Height : integer; {}

Constructor Init(ix,iy:integer; {кординаты}

iWidth,IHeight:integer; {}

icolor: byte); {цвет}

procedure Show;virtual;

end;

еперь введем два новых класса видимых объектов – ”Окружности” и ”Прямоугольники”, которые объявим потомками класса ”Точки”. Приведем их объявления:

Оба класса являются потомками класса TPoint и в силу этого наследуют все методы родительского класса. Из объявления классов потомков видно, что для них требуется всего два метода – конструктор иShow. Наличиеконструктора обязательно для любого класса объектов, если дочерний класс имеет новые свойства (поля). А методShow необходим в связи с тем, что объекты каждого класса ”выглядят” иначе, чем другие.

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

А теперь можно вернуться к объяснению назначения атрибута virtual. При рассмотрении классаTPointмы описали логику методаHide следующим образом: установить цвет объекта равным цвету фона и выполнить его (объекта) метод Show. В этом описании никак не детализировался алгоритм последнего метода: Мы использовали то обстоятельство, что объект сам себя умеет нарисовать. Но такое же утвердение справедливо и для объектов вновь объявленных классов – они тоже умеют себя нарисовать, и следовательно, алгоритм унаследованного ими метода Hide полностью подходит и для них (потомков).

Единственная проблема, которая может оказаться существенной – в методе Hide нет указания того, какому классу принадлежит вызываемый в нем метод Show.Так вот, если в объявлении класса TPoint убрать атрибут virtual, то при выполнении метода Hide будет вызываться метод Show класса TPoint, а при его наличии будет осуществляться поиск метода Show в том классе, которому принадлежит объект. Именно по этой причине в объявлении новых классов даже не упоминается виртуальный метод Hide, хотя его логика соответствует объектам именно этх классов.

Ниже приведено объявление еще одного класса – строки текста. Этот класс построен как потомок класса TRect. Выбор такого наследования связан с тем, что срока текста занимает прямоугольник. Как расположена точка «привязки» этого прямоугольника относительно текста, можно увидеть из конструктора класса (TText.Init). А его методShowпоказывает, как будет выглядеть объект.

Type

PText = ^TText;

TText = object(TRect) {потомок класса Прямоугольник}

Txt:string; {текст, отображаемый на экране}

Constructor Init(ix,iy:integer; {кординаты}

itext:string; {текст}

icolor: byte); {цвет}

procedure Show;virtual;

end;

Constructor TText.Init(ix,iy:integer; {кординаты}

itext:string; {текст}

icolor: byte); {цвет}

var

w,h:integer;

begin

w:=(Length(itext)+2)*TextWidth('W');

h:=2*TextHeight('W');

Inherited Init(ix,iy,w,h,icolor);

txt:=itext;

end;

procedure TText.Show;

var

TempColor:byte;

begin

TempColor:=GetColor;

SetTextJustify(CenterText,CenterText);

SetColor(color);

OutTextXY(x+width div 2,y+height div 2,txt);

SetColor(TempColor);

Visible:=true;

end;

Ниже приведен фрагмент программы, иллюстрирующий работу с объектами описанных классов.

. . . .

var

c1:PCircle;

r1:PRect;

t1:PText;

. . . .

begin

. . . .

Инициализация графического режима (Здесь не показана)

. . . .

New(c1, Init(120,120,20,Yellow));{создание

объекта «окружность»}

c1^.Show;

c1^.Drag(2);

Dispose(c1, Done); {уничтожение объекта «окружность»}

Продолжение на следующей странице

New(r1, Init(10,10,45,20,red)); {создание объекта

«прямоугольник»}

r1^.Show;

r1^.MoveTo(50,24);

New(t1, Init(300,300,'Example',Magenta)); {создание объекта

«строка текста»}

t1^.Show;

t1^.Drag(5);

repeat until KeyPressed;

CloseGraph;

end.

Соседние файлы в папке лекции