Материал: Мансуров. Основы программирования в среде Lazarus. 2010

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Глава 5 Основы объектно-ориентированного программирования

____________________________________________________________________

Student.group:= '"ПОВТАС-1/09"';

fname:= Student.GetData;

writeln(UTF8ToConsole('Это: ' + fname));

Professor.name:= 'Иван';

Professor.fam:= 'Иванов';

Professor.kafedra:='"Программирование"';

fname:= Professor.GetData;

writeln(UTF8ToConsole('Это: ' + fname)); writeln(UTF8ToConsole('Нажмите любую клавишу'));

readkey;

Student.Free;

Professor.Free;

end.

Посмотрите на реализации методов GetData. В чем-то они похожи. Осо-

бенно если мы перепишем их в виде:

function TStudent.GetData: string; begin

Result:= name + ' ' + fam;

Result:= Result + ', группа ' + group; end;

function TProfessor.GetData: string; begin

Result:= name + ' ' + fam;

Result:= Result + ', кафедра ' + kafedra; end;

Первые операторы этих функций совпадают с методом родительского класса. Это в наших примерах методы очень простые. В реальности методы мо-

441

5.5. Полиморфизм

____________________________________________________________________

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

Конечно же, нет! Оказывается можно вызывать метод родительского класса с помощью ключевого слова inherited. Например:

function TStudent.GetData: string; begin

Result:= inherited GetData;

Result:= Result + ', группа ' + group;

end;

Здесь сначала вызывается метод родительского класса, а затем добавляется новый код.

5.5.2 Позднее связывание.

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

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

какому объекту (экземпляру класса) относится метод. Рассмотрим пример.

Пусть нам необходимо, чтобы на экран выводилась кроме прежней информа-

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

GetData. Во время компиляции неизвестно, объект какого класса вызывает метод Status. Это определяется на этапе выполнения, когда точно известен активный в данный момент объект. Разрешение связей на этапе выполнения на-

зывается поздним связыванием. Для реализации механизма позднего связыва-

ния применяются ключевые слова virtual и override. Метод родительско-

го класса помечается ключевым словом virtual. Методы дочерних классов,

442

Глава 5 Основы объектно-ориентированного программирования

____________________________________________________________________

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

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

Рассмотрим пример.

unit Unit1;

{$mode objfpc}{$H+} interface

uses

Classes, SysUtils; type

{ THuman } THuman = class

private

Fname: string;

Ffam: string;

procedure Setname(const AValue: string); procedure Setfam(const AValue: string);

public

property name: string read Fname write Setname; property fam: string read Ffam write Setfam; function GetData: string;

function Status: string; virtual; end;

implementation { THuman }

procedure THuman.Setname(const AValue: string); begin

443

5.5. Полиморфизм

____________________________________________________________________

if Fname=AValue then exit; Fname:=AValue;

end;

procedure THuman.Setfam(const AValue: string); begin

if Ffam=AValue then exit; Ffam:=AValue;

end;

function THuman.Status: string; begin

end;

function THuman.GetData: string; begin

Result:= name + ' ' + fam + Status; end;

end.

program project1; {$mode objfpc}{$H+} uses

CRT, FileUtil, Unit1; type

TStudent = class(THuman) private

444

Глава 5 Основы объектно-ориентированного программирования

____________________________________________________________________

group: string; public

function GetData: string; function Status: string; override;

end;

function TStudent.Status: string; begin

Result:= ' - студент'; end;

function TStudent.GetData: string; begin

Result:= inherited GetData + ', группа ' + group; end;

type

TProfessor = class(THuman) private

kafedra: string; public

function GetData: string; function Status: string; override;

end;

function TProfessor.Status: string; begin

Result:= ' - преподаватель'; end;

function TProfessor.GetData: string;

445

Смотрите также:

1 — пак
11 Горм +
113
14
1433
1511
1632
199
204
2714