Загрузка данных


{$mode objfpc}{$H+}
{$codepage UTF-8}
unit geometry;

interface

uses
  SysUtils;

type
  IPrintable = interface
    ['{719CBE78-0F14-41EB-98D7-CDFF6A5C09F4}']
    procedure PrintInfo;
  end;

  TGeomShape = class(TObject)
  strict private
    FName: string;
  public
    constructor Create(const AName: string);
    destructor Destroy; override;
    function Area: Double; virtual; abstract;
    function Perimeter: Double; virtual; abstract;
    property Name: string read FName;
  end;

  TCircle = class(TGeomShape, IPrintable)
  strict private
    FRadius: Double;
  public
    constructor Create(const AName: string; ARadius: Double);
    function Area: Double; override;
    function Perimeter: Double; override;
    procedure PrintInfo;
  end;

  TRectangle = class(TGeomShape, IPrintable)
  strict private
    FWidth: Double;
    FHeight: Double;
  public
    constructor Create(const AName: string; AWidth, AHeight: Double);
    function Area: Double; override;
    function Perimeter: Double; override;
    procedure PrintInfo;
  end;

  TTriangle = class(TGeomShape, IPrintable)
  strict private
    FA: Double;
    FB: Double;
  public
    constructor Create(const AName: string; AA, AB: Double);
    function Area: Double; override;
    function Perimeter: Double; override;
    procedure PrintInfo;
  end;

  TShapeCatalog = class(TObject)
  strict private
    FShapes: array of TGeomShape;
  public
    destructor Destroy; override;
    procedure Add(AShape: TGeomShape);
    function Count: Integer;
    function GetShape(Index: Integer): TGeomShape;
    procedure PrintAll;
    function TotalArea: Double;
    function TotalPerimeter: Double;
  end;

implementation

{ TGeomShape }

constructor TGeomShape.Create(const AName: string);
begin
  inherited Create;
  FName := AName;
end;

destructor TGeomShape.Destroy;
begin
  inherited Destroy;
end;

{ TCircle }

constructor TCircle.Create(const AName: string; ARadius: Double);
begin
  inherited Create(AName);
  FRadius := ARadius;
end;

function TCircle.Area: Double;
begin
  Result := Pi * FRadius * FRadius;
end;

function TCircle.Perimeter: Double;
begin
  Result := 2 * Pi * FRadius;
end;

procedure TCircle.PrintInfo;
begin
  WriteLn(Format('Круг «%s»: R=%s, S=%s, P=%s', [
    Name,
    FormatFloat('0.00', FRadius),
    FormatFloat('0.00', Area),
    FormatFloat('0.00', Perimeter)
  ]));
end;

{ TRectangle }

constructor TRectangle.Create(const AName: string; AWidth, AHeight: Double);
begin
  inherited Create(AName);
  FWidth := AWidth;
  FHeight := AHeight;
end;

function TRectangle.Area: Double;
begin
  Result := FWidth * FHeight;
end;

function TRectangle.Perimeter: Double;
begin
  Result := 2 * (FWidth + FHeight);
end;

procedure TRectangle.PrintInfo;
begin
  WriteLn(Format('Прямоугольник «%s»: W=%s, H=%s, S=%s, P=%s', [
    Name,
    FormatFloat('0.00', FWidth),
    FormatFloat('0.00', FHeight),
    FormatFloat('0.00', Area),
    FormatFloat('0.00', Perimeter)
  ]));
end;

{ TTriangle }

constructor TTriangle.Create(const AName: string; AA, AB: Double);
begin
  inherited Create(AName);
  FA := AA;
  FB := AB;
end;

function TTriangle.Area: Double;
begin
  Result := FA * FB / 2;
end;

function TTriangle.Perimeter: Double;
begin
  Result := FA + FB + Sqrt(FA * FA + FB * FB);
end;

procedure TTriangle.PrintInfo;
begin
  WriteLn(Format('Треугольник «%s»: A=%s, B=%s, S=%s, P=%s', [
    Name,
    FormatFloat('0.00', FA),
    FormatFloat('0.00', FB),
    FormatFloat('0.00', Area),
    FormatFloat('0.00', Perimeter)
  ]));
end;

{ TShapeCatalog }

destructor TShapeCatalog.Destroy;
var
  I: Integer;
begin
  for I := 0 to High(FShapes) do
    FShapes[I].Free;
  SetLength(FShapes, 0);
  inherited Destroy;
end;

procedure TShapeCatalog.Add(AShape: TGeomShape);
begin
  SetLength(FShapes, Length(FShapes) + 1);
  FShapes[High(FShapes)] := AShape;
end;

function TShapeCatalog.Count: Integer;
begin
  Result := Length(FShapes);
end;

function TShapeCatalog.GetShape(Index: Integer): TGeomShape;
begin
  Result := FShapes[Index];
end;

procedure TShapeCatalog.PrintAll;
var
  I: Integer;
  P: IPrintable;
begin
  for I := 0 to High(FShapes) do
  begin
    Write('  ', I + 1, '. ');
    if Supports(FShapes[I], IPrintable, P) then
      P.PrintInfo;
  end;
end;

function TShapeCatalog.TotalArea: Double;
var
  I: Integer;
begin
  Result := 0;
  for I := 0 to High(FShapes) do
    Result := Result + FShapes[I].Area;
end;

function TShapeCatalog.TotalPerimeter: Double;
var
  I: Integer;
begin
  Result := 0;
  for I := 0 to High(FShapes) do
    Result := Result + FShapes[I].Perimeter;
end;

end.