Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Объектно-ориентированное программирование.docx
Скачиваний:
20
Добавлен:
31.08.2019
Размер:
112.85 Кб
Скачать
  1. Конструкторы и деструкторы.

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

Конструкторы и деструкторы - это специальные методы класса. Разумеется, эти методы обладают целым рядом особенностей (именно по этому они и выделены в специальную группу). Их особенности:

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

Второе. В отличии от других методов конструктор и деструктор вызываются сами (а другие методы мы вызываем явным образом). Конструктор вызывается в момент создания экземпляра класса, а деструктор - в момент уничтожения. Т. е. их не надо вызывать явным образом - они вызываются сами. Именно поэтому конструкторы обычно используются для задания некоторых начальных значений для переменных класса, а деструкторы - для освобождения памяти (в случае если у вас есть внутри класса переменные-указатели).

Третье. Ни конструктор, ни деструктор не возвращают никакого значения (даже типа void). Это означает, в частности, что при обяъвлении конструтора и деструктора в классе мы перед ними не пишем ни какой тип.

Четвертое. В классе может быть несколько конструкторов (и они должны различаться параметрами), и только один деструктор (у него параметров вообще быть не может).

Наследование объектов

Мы уже знаем, что такое наследование. Теперь предстоит познакомиться с

этой возможностью на практике. Допустим, что у нас есть объект, описы-

вающий точку, — TMyPoint. Он может выглядеть следующим образом:

TmyPoint = class

protected

PointX, PointY:Integer;

public

constructor Create(X,Y : Integer); virtual;

procedure Draw; virtual;

end; '

В данном случае у нас объект, который не имеет предков. В таких случаях

берется базовый объект TObject. Он дает нам базовые функции, необходи-

мые любому объекту. В разделе protected объявлены две переменные

PointX и PointY, которые будут являться координатами точки. Это значит,

что доступ к ним сможет получить только этот объект или его потомок.

В разделе public объявлены две процедуры, которые будут доступны всем.

Первая — это конструктор (constructor) с именем create. Конструктор —

это такая же процедура, только вместо ключевого слова procedure нужно

написать constructor и дать имя create. Этой процедурой мы будем созда-

вать данный объект во время выполнения программы. Внутри ее можно вы-

полнить какие-то начальные действия (выделить необходимую память, уста-

новить значение переменных по умолчанию и т. д.).

В данном случае конструктору передаются координаты точки, и в нем мы

можем сохранить эти значения, используя переменные Pointx и PointY.

Вот как это будет выглядеть:

constructor TMyPoint.Create(X, Y: Integer);

begin

PointX:=X;

PointY:=Y;

.

end;

Основы языка программирования Delphi 121

Процедуру Draw мы не будем описывать, просто представим, что она выво-

дит на экран точку.

Конструктор и процедура у нашего объекта объявлены виртуальными. Об

этом говорит соответствующее ключевое слово (virtual) в конце объявле-

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

конструктора и метода рисования.

Теперь допустим, что требуется создать объект линии. Для этого нам нужно

описать свойства четырех координат, конструктор и метод рисования. Мож-

но все это создать с нуля, а можно вывести из объекта точки, который уже

имеет половину необходимого. Объявление объекта линии может выглядеть

примерно так:

TmyLine = class (TMyPoint)

protected

PointXl, PointYl:Integer;

public

constructor Create(X,Y,XI,Yl : Integer); reintroduce;

procedure Draw; override;

end;

Этот объект у нас является наследником от TMyPoint, а значит, наследует

все его свойства и методы. О том, что у нас объект наследник, говорится в

объявлении имени базового объекта (в скобках после ключевого слова

class).

В этом объекте объявлены две переменные Pointxi и PointYl, которые

описывают координаты второй точки. Координаты первой точки наследуются

из базового объекта, поэтому нам не надо их описывать.

Метод create уже содержит четыре параметра, которые будут описывать

координаты двух точек. После объявления этого метода стоит ключевое сло-

во reintroduce. Зачем оно нужно? У базового объекта тоже есть конструк-

тор, но у него два параметра, а у нашего конструктора четыре. Когда мы пе-

реопределяем метод и в новой версии количество параметров изменилось,

то мы должны поставить такое ключевое слово, чтобы показать компилято-

ру, что мы изменили параметры корректно.

Реализация конструктора может выглядеть следующим образом:

Constructor TMyLine.Create(X,Y,X1,Yl:Integer);

begin

inherited Create(X,Y);

PointXl:=X1;

PointYl:=Y1;

end;

/22 Глава 5

В самом начале стоит ключевое слово inherited. Этим мы говорим, что

нужно вызвать конструктор предка (объекта TMyPoint). После этого ключе-

вого слова мы пишем имя конструктора предка и указываем, какие пара-

метры нужно ему передать. В данном случае передаются координаты первой

точки. Предок сохранит эти координаты в переменных Pointx и Pointy.

Когда количество параметров у предка и наследника одинаковое, то можно

ПрОСТО указать КЛЮЧеВОе СЛОВО inherited;.

После этого мы сохраняем координаты второй точки в переменных Pointxi

И PointYl.

'

После объявления метода Draw у нас стоит ключевое слово override. Оно

говорит о том, что мы перекрываем такой же виртуальный метод в объекте

предка.

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

а пока с теорией закончим.

Внутри каждого объекта существует переменная Self, которая указывает на

него самого. Если вам нужно обратиться к переменной или методу объекта,

явно указав принадлежность, то можно написать self .имя. В принципе, эту

переменную мы будем использовать, когда нужно вызвать какую-то про-

цедуру и передать ей объект, из которого мы делали вызов.

CallFunc(Self);

В приведенном выше примере мы вызвали процедуру CallFunc, а в качестве

параметра передали текущий объект.