Особенности использования объектов

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

Листинг 1.10

Var

A, B: TMySimpleClass; // Переменные A и B не связаны с объектом

Begin

A := TMySimpleClass.Create; // Связывание переменной A с новым объектом

// Переменная B пока еще не связана ни с каким объектом

B := A; // Связывание переменной B с тем же объектом, что и A

// Теперь обе переменные связаны с одним объектом

B.Free; // Уничтожение объекта

// Теперь A и B не связаны ни с каким объектом

end;

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

С объектами-наследниками можно работать так же как и с объектами-родителями. Это, например, позволяет держать в одном массиве родственный объекты разных классов, а не создавать несколько отдельных массивов.

Пусть перед нами стоит задача рисования некоторых геометрических фигур. Возьмём прямоугольник и круг. Создадим для них два класса, наследуемых от абстрактного класса фигура. Далее поместим объекты обоих классов в один массив и будем по очереди вызовать для каждого объекта метод Draw().

Листинг 1.11

Type

TFigure= class(TObject)

procedure Draw();virtual;abstract;

end;

TRectangle = class(TFigure)

fx,fy:integer;

procedure Draw();override;

end;

TCircle = class(TFigure)

fR:integer;

procedure Draw();override;

end;

var A:array [1..3] of TFigure;

i:integer;

procedure TRectangle.Draw;

Begin

inherited;

ShowMessage('Rectangle');

end;

procedure TCircle.Draw;

Begin

inherited;

ShowMessage('Circle');

end;

//данный код поместить в обработчик нажатия кнопки

A[1]:=TRectangle.Create();

A[2]:=TCircle.Create();

A[3]:=TRectangle.Create();

for i:=1 to 3 do A[i].Draw();

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

TRectangle(a[1]).x:=2;

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

Расширенное описание класса.

Помимо использования обычных полей (переменных) и методов (функций) в objectpascal встречаются их некоторые модификации. Это свойства, события, обработчики событий. В общем виде класс имеет следующую структуру (пример):

Листинг 1.12

TMyRectangle = class(TObject)

Public //раздел конструкторов и деструкторов

constructor Create; overload; //конструкторпоумолчанию

constructor Create(width,height: integer); overload; //параметрич. конструктор

Protected //в защищённом разделе находятся поля объекта

Fw: integer; //ширина - поле

FhTeg: integer; //высота - поле

Protected //раздел методов для работы со свойствами

procedureSetwidth(width:integer); //установка значения ширины - метод

function Getwidth: integer; //получение значения ширины - метод

procedureSetHeight(height:integer); //установка значения ширины - метод

function GetHeight: integer; //получение значения ширины - метод

Public //разделсвойств

property width: integer read getwidth write setwidth default 100; //свойствообъекта - ширина

property height: integer read getHeight write setHeight default 50; //свойствообъекта – высота

Protected //закрытый раздел для внутренних методов

function FindRound: real; //расчётскругления - метод

Public //раздел открытых методов для доступа к классу из вне

procedure Draw (canvas: TCanvas); //рисование - метод

Public //обработчикивнешнихсобытий

procedure WMKeyDown(var Msg: TWMKeyDown); message WM_KEYDOWN; //нажатиеклавиши

Protected //внутренние события

FOnResizeEvent: TNotifyEvent; //возникает при изменении размеров

Public//published если это компонент - внешнее отображение события

property OnResize: TNotifyEvent read FOnResizeEvent write FOnResizeEvent;

Наши рекомендации