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

Методическое пособие 555

.pdf
Скачиваний:
4
Добавлен:
30.04.2022
Размер:
2.33 Mб
Скачать

объектная_переменная.имя_свойства := выражение;

В PascalABC.Net при описании свойства вместо getметода можно указать имя соответствующего поля:

property имя_свойства: тип read имя_поля write set_метод;

Вэтом случае объявлять функцию чтения нет необходимости. Рассмотрим следующий пример:

type

Person = class private

nm: string; //имя ag: integer; //возраст

procedure setAge(a: integer); begin

if a>0 then ag := a

else

a := 0;

end;

function getId: string; begin

getID := nm + IntToStr(ag); end;

public

property Age: integer read ag write setAge;

property Name: string read nm; property Id: string read getId;

end;

var p: Person;

141

begin

p := new Person;

p.Age := 58;//Изменение значения свойства

Age

//будет вызвана процедура

SetAge

writeln(p.Id); //будет вызвана функция GetId

end.

В этом примере класс person содержит два приватных поля nm (имя) и ag (возраст), приватные методы setAge и getId, и три публичных свойства: Age, Name и Id. Свойства Age и Name ассоциированы с полями nm и ag. Метод SetAge является set-методом для свойства Age и изменяет значение ассоциированного с этим свойством поля ag. Роль get-методов для свойств Age и Name играют соответственно поля ag и nm – значения этих полей будут подставлены в случае доступа к свойствам на чтение. Метод getId является getметодом для свойства Id, данный метод возвращает строку, являющуюся суммой строк nm и IntToStr(ag) (имя и возраст).

1.4. Наследование классов и полиморфизм

Класс может быть унаследован от другого класса. Класс, от которого наследуют, называют базовым классом (надклассом, предком), а класс, который наследуется, называется производным классом (подклассом, потомком). При описании класса его базовый класс указывается в скобках после слова class.

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

142

Например:

type

BaseClass = class a: Real; procedure p;

procedure r(i: Integer); end;

MyClass = class(BaseClass) procedure r(i: Integer);

end;

В этом примере для класса BaseClass имя классапредка не указано, поэтому он наследуется от класса Object (предка всех классов).

Класс MyClass наследуется от класса BaseClass, при этом поле a и метод p добавляется в класс MyClass. Метод r класса-потомка MyClass имеет то же имя, что и в классе-предке BaseClass. При этом происходит переопределение метода: при вызове метода r для объекта класса MyClass выполняется метод, определенный в классе

MyClass.

Если после переопределения метода в классе-потомке требуется вызвать метод базового класса, то используется служебное слово inherited (унаследованный).

1.5.Перегрузка методов

ВPascalABC.Net можно объявлять подпрограммы с одним именем, но разным количеством или типами параметров. Имена таких процедур и функций называются перегружен-

ными.

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

143

procedure p(b: Integer); procedure p(r: Real);

при вызове p(1.0) будет выбрана перегруженная процедура с параметром типа Real, а при вызове p(1) будет выбрана перегруженная процедура с параметром типа Integer.

Если выбор из перегруженных процедур невозможен (ни одна не подходит или обе подходят одинаково хорошо), то компилятор сообщит об ошибке.

Если класс-потомок содержит метод, имя которого совпадает с одним из методов базового класса, но число и/или тип параметров отличаются, то этот метод будет не переопределять (как это описано в п. 1.4), а перегружать метод базового класса.

Как и переопределение методов, перегрузка является одним из механизмов реализации принципа полиморфизма.

Отметим, что перегружать можно не только подпрограммы, но и операции. Например, можно перегрузить арифметический оператор + таким образом, чтобы он позволял складывать не только числа, но и объекты некоторого класса. Подробнее о перегрузке операций можно прочитать в справочной системе PascalABC.Net (Справка->Справочник по языку->Классы->Перегрузка операций).

1.5. Конструкторы и деструкторы

Для создания и удаления объектов используются специальные методы, называемые конструкторами и деструкто-

рами.

Конструктор представляет собой функцию, создающую объект в динамической памяти, инициализирующую его поля и возвращающую указатель на созданный объект. Этот указатель обычно сразу присваивается переменной типа класс. При описании конструктора вместо служебного слова function используется слово constructor, тип возвращаемого значения не указывается. Например:

144

type

Person = class private

nm: string; //имя ag: integer; //возраст

public

constructor Create(name: Strig; age: Integer;)

end;

constructor Person.Create(name: string; age: integer);

begin

nm := name; //инициализация полей объекта ag := age;

end;

Для вызова конструктора можно использовать два способа (первый – в стиле языка Object Pascal, второй – в стиле C#):

1) var p: Person;

p:= Person.Create('Иванов',20);

2)var p: Person;

p:= new Person('Иванов',20);

В языке ObjectPascal при удалении объекта вызывается процедура-деструктор, уничтожающая объект и освобождающая динамическую память, выделенную ранее под этот объект. Ее описание имеет вид:

destructor Destroy; begin

...

end;

145

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

2. Практическая часть

Задание 1. Создать класс VehicleClass (англ. vehicle

транспортное средство), содержащий:

приватные поля Liters (объем цилиндров в литрах), Vx (количество цилиндров), Horses (мощность двигателя в л.с.), RPMs (обороты двигателя в минуту);

публичные свойства EngineSize, Cylinders, HR,

RPM, служащие интерфейсами для доступа к полям Liters, Vx, Horses и RPMs соответственно;

приватные set -методы для указанных выше свойств.

Решение. Описание соответствующего класса представлено ниже.

type

//Класс транспортного средства

VehicleClass = class private

Liters: Real; {Объем цилиндров в литрах} Vx: Integer; {Количество цилиндров} Horses: Integer; {Мощность двигателя в л.с.} RPMs: Integer; {Обороты двигателя в минуту}

//Set-методы

procedure SetEngineSize(ltrs: Real); begin

Liters := ltrs; end;

procedure SetCylinders(cyl: Integer); begin

146

Liters := cyl; end;

procedure SetHP(hpwr: Integer); begin

Horses := hpwr; end;

procedure SetRPM(RevPerMin: Integer); begin

RPMs := RevPerMin; end;

public

//Свойства

property EngineSize: Real read Liters

write SetEngineSize; property Cylinders: Integer read Vx

write SetCylinders; property HP: Integer read Horses write SetHP; property RPM: Integer read RPMs write SetRPM;

end;

Задание 2. Добавьте в класс VehicleClass публичную функцию Describe, которая возвращает строку с описанием объекта класса VehicleClass. Пример содержания такой строки:

’1.6 л., V4, 106 л.с., 5500 об/мин ’

Решение. Описание функции Describe представлено ниже. Добавьте это описание в публичную секцию класса

VehicleClass.

function Describe: string; begin

Describe := FloatToStr(EngineSize) + 'л., V' + IntToStr(Vx) + ', ' +

IntToStr(Horses) + ' л.с.,' + IntToStr(RPMs) + ' об/мин';

end;

147

Задание 3. Добавьте в класс VehicleClass публичную процедуру SetAll, устанавливающую все свойства объекта данного класса.

Решение. Добавьте следующее описание процедуры SetAll в публичную секцию класса VehicleClass.

procedure SetAll(eng: Real; cyl, hpwr,rev: Integer);

begin

Liters := eng; Vx := cyl; Horses := hpwr; RPMs := rev;

end;

Задание 4. Создайте новый класс MotorcycleClass (класс мотоцикла), дочерний по отношению к классу VehicleClass (все свойства и методы класса-предка будут унаследованы). Добавьте в новый класс его собственные методы и свойства:

приватные поля TankSize (объем топливного бака в литрах) и ExtColor (цвет кузова);

публичные свойcтва FuelTank и Exterior, слу-

жащие интерфейсами для доступа к полям TankSize

иExtColor соответственно;

приватные set -методы для указанных выше свойств;

публичную функцию Describe, переопределяющую одноименную функцию класса-предка VehicleClass и выводящую информацию об объекте в виде строки, например

3.4л., V5, 52 л.с.,5900 об/мин,

16.9литров в баке, Цвет кузова - черный

-публичную процедуру SetAll, перегружающую одноименную процедуру класса-предка VehicleClass и задающую все свойства объекта класса MotorcycleClass.

148

Решение. Описание класса MotorcycleClass и его методов представлено ниже. Добавьте это описание в программу.

//Класс мотоцикла

MotorcycleClass = class(VehicleClass) private

TankSize: Real;//Объем топливного бака в литрах

ExtColor: String; //Цвет кузова

//Set методы

procedure SetCapacity(tank: Real); begin

TankSize := tank; end;

procedure SetExtColor(color: String); begin

ExtColor := color; end;

public

//свойства

property FuelTank: Real read TankSize write SetCapacity;

property Exterior: String read ExtColor

write SetExtColor; //методы (полное описание – позднее)

function Describe: String;

procedure SetAll(eng: Real; cyl, hpwr,

rev: Integer; tank: Real; color: String);

end;

//Полный текст методов класса MotorcycleClass function MotorCycleClass.Describe: String; var

tank: String; begin

149

//Вызов метода Describe класса-предка

//(ключевое слово inherited) Result := inherited Describe;

//Преобразуем число TankSize в строку и //поместим эту строку в переменную tank

Str(TankSize:4:1, tank);

//Формируем строку описания объекта (мотоцикла)

Result := Result + ', ' + tank +

' литров в баке, ' + 'Цвет кузова - ' + ExtColor; end;

procedure MotorcycleClass.SetAll(eng: Real; cyl, hpwr, rev: Integer; tank: Real; color: String);

begin

//Вызов метода SetAll родительского класса inherited SetAll(eng, cyl, hpwr, rev) ;

//Дополнительно задаем свойства, //отсутствовавшие в родительском классе

TankSize := tank; ExtColor := color;

end;

Задание 5. Добавьте в класс MotorcycleClass публичный метод (процедуру) Initialize, который инициализирует объект данного класса путем присвоения всем свойст-

вам значений по умолчанию.

 

 

 

Указание.

Добавьте

в

секцию

public

класса MotorcycleClass метод

 

 

procedure Initialize;

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

150