Einzelnen Beitrag anzeigen

Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#13

AW: Warum und wann eine Klasse benutzen

  Alt 16. Okt 2013, 20:36
Ein weiterer, sehr toller Aspekt an OOP ist Polymorphie. Für mich ist das vielleicht sogar der entscheidende Punkt, da man ihn im Gegensatz zu Kapselung und Vererbung eigentlich nicht gescheit ohne Klassen simulieren kann (technisch möglich ist es natürlich, ist dann aber nicht mehr wirklich eleganter als Alternativen).

Delphi-Quellcode:
type
  TShape = class
  protected
    FLeft, FTop, FSize: integer;
  public
    procedure DrawTo(Canvas: TCanvas); virtual; abstract;
    property Left: integer read FLeft write FLeft;
    property Top: integer read FTop write FTop;
    property Size: integer read FSize write FSize;
  end;

  TCircle = class(TShape)
  public
    procedure DrawTo(Canvas: TCanvas); override;
  end;

  TSquare = class(TShape)
  public
    procedure DrawTo(Canvas: TCanvas); override;
  end;

implementation

procedure TCircle.DrawTo(Canvas: TCanvas);
begin
  Canvas.Ellipse(Left, Top, Left + Size, Top + Size);
end;

procedure TSquare.DrawTo(Canvas: TCanvas);
begin
  Canvas.Rectangle(Left, Top, Left + Size, Top + Size);
end;
Delphi-Quellcode:
type
  TMyForm = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormPaint(Sender: TObject);
  private
    FShapes: array[0..4] of TShape;
  end;

implementation

procedure TMyForm.FormCreate(Sender: TObject);
begin
  // *Irgendwelche* Formen z.B. in einem Array/Liste speichern.
  // Konkreter Typ ist egal, solange sie nur von TShape erben.
  for i := low(Shapes) to high(Shapes) do
  begin
    if Odd(i) then
      Shapes[i] := TCircle.Create
    else
      Shapes[i] := TSquare.Create;

    Shapes[i].Size := i * 5;
    Shapes[i].Left := i * 20;
    Shapes[i].Top := 0;
  end;
end;

procedure TMyForm.FormPaint(Sender: TObject);
begin
  // Wir können jetzt alle diese verschiedenen Objekte mit dem gleichen
  // Code verarbeiten, obwohl es sich um verschiedenartige Klassen
  // handelt und jeweils spezialisierter Code ausgeführt wird
  // -> man spart sich u.U. etliche Case-Strukturen, die den Code
  // sonst unübersichtlich und fehleranfällig machen würden
  for i := low(Shapes) to high(Shapes) do
    Shapes[i].DrawTo(Canvas);
end;

procedure TMyForm.FormDestroy(Sender: TObject);
begin
  for i := low(Shapes) to high(Shapes) do
    Shapes[i].Free;
end;
Mit records geht das einfach nicht so schön... vor allem nicht, wenn man später das Programm leicht um weitere Spezialisierungen erweitern können will.