{$mode objfpc} {$h+} {$modeswitch duplicatelocals}
uses
SysUtils;
type
IVegetable = interface;
TVegetable = class;
IVegetableGarden = interface
procedure Plant(const v: IVegetable);
procedure RollCall;
function GetName: string;
property name: string read GetName;
end;
TVegetableGarden = class(TInterfacedObject, IVegetableGarden)
name: string;
constructor Create(const name: string);
destructor Destroy; override;
procedure Plant(const v: IVegetable);
procedure RollCall;
function GetName: string;
private
vegetables: array of IVegetable;
end;
IVegetable = interface
procedure RespondToRollCall;
procedure SetGarden(const garden: TVegetableGarden);
end;
TVegetable = class(TInterfacedObject, IVegetable)
garden: TVegetableGarden;
name: string;
weight: single;
constructor Create(const name: string; const weight: single);
destructor Destroy; override;
procedure RespondToRollCall;
procedure SetGarden(const garden: TVegetableGarden);
end;
constructor TVegetableGarden.Create(const name: string);
begin
inherited Create;
self.name := name;
end;
destructor TVegetableGarden.Destroy;
var
i: SizeInt;
begin
writeln('Огород «', name, '» уничтожается.');
for i := 0 to High(vegetables) do
vegetables[i].SetGarden(nil);
inherited Destroy;
end;
procedure TVegetableGarden.Plant(const v: IVegetable);
begin
SetLength(vegetables, length(vegetables) + 1);
vegetables[High(vegetables)] := v;
v.SetGarden(self);
end;
procedure TVegetableGarden.RollCall;
var
i: SizeInt;
begin
for i := 0 to High(vegetables) do
vegetables[i].RespondToRollCall;
end;
function TVegetableGarden.GetName: string;
begin
result := name;
end;
constructor TVegetable.Create(const name: string; const weight: single);
begin
inherited Create;
self.name := name;
self.weight := weight;
end;
destructor TVegetable.Destroy;
begin
writeln('Овощ «', name, '» уничтожается.');
inherited Destroy;
end;
procedure TVegetable.RespondToRollCall;
begin
writeln('<', garden.name, '>: ', name, ', вес ', FloatToStrF(weight, ffGeneral, 6, 0), ' кг');
end;
procedure TVegetable.SetGarden(const garden: TVegetableGarden);
begin
self.garden := garden;
end;
procedure Main;
var
garden: IVegetableGarden;
begin
garden := TVegetableGarden.Create('ОВОЩИ');
garden.Plant(TVegetable.Create('картофель', 1.4));
garden.Plant(TVegetable.Create('чеснок', 0.05));
garden.Plant(TVegetable.Create('Рируру', 54));
garden.Plant(TVegetable.Create('PoppyFanboy', 65));
garden.RollCall;
end;
begin
Main;
end.