Schritt für Schritt zur klassenbasierten Programmierung - Teil 4

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Schritt für Schritt zur klassenbasierten Programmierung - Teil 4

Beitrag von fliegermichl »

Im letzten Artikel hatte ich beschrieben, was Felder und Methoden sind und das Klassen von anderen abgeleitet werden können.
Darum soll es hier jetzt gehen.

Wir wollen ein paar geometrische Figuren definieren, die von TGeo abgeleitet werden.
Im einzelnen ein Rechteck, eine Ellipse, ein Kreis und ein Dreieck.

Um Rechtecke definieren zu können, brauchen wir zusätzlich zur Position noch eine Höhe und eine Breite. Das gleiche gilt für Ellipse und Dreieck. Beim Kreis benötigen wir stattdessen einen Radius oder einen Durchmesser.

Wie im letzten Artikel beschrieben, müssen konkrete geometrische Objekte die Methode Draw überschreiben. Das wollen wir jetzt machen.

Im interface Teil der unit werden diese abgeleiteten Klassen definiert:

Code: Alles auswählen

  TRechteck = class ( TGeo )
    fBreite,
    fHoehe : integer;
    procedure Draw(Canvas : TCanvas); override;
  end;

  TEllipse = class ( TRechteck )
    procedure Draw(Canvas : TCanvas); override;
  end;

  TDreieck = class ( TRechteck )
    procedure Draw(Canvas : TCanvas); override;
  end;

  TKreis = class ( TGeo )
    fRadius : integer;
    procedure Draw(Canvas : TCanvas); override;
  end;
Wenn man in einer abgeleiteten Klasse eine virtuelle Methode überschreibt, so muß dies durch den Bezeichner override geschehen.

Die von TGeo abgeleitete Klasse TRechteck definiert lediglich die beiden neuen Felder fBreite und fHoehe sowie die Methode Draw zum zeichnen.
TEllipse und TDreieck definieren gar keine eigenen Felder sondern werden von TRechteck abgeleitet. Sie verfügen dadurch automatisch neben der Position, die von TGeo geerbt wurde auch ueber die Felder fBreite und fHoehe. Lediglich die Darstellung mit Draw muß angepasst werden.

Da der Kreis weder Breite noch Höhe hat, wird er direkt von TGeo abgeleitet und erhält als einziges Feld fRadius.
Nachfolgend die Draw Methoden der von TGeo abgeleiteten Klassen. Ich bin hierbei davon ausgegangen, daß die Position jeweils im Zentrum der geometrischen Figur liegt.

Nachfolgend die Implementation der Methode Draw zu den besagten Klassen. (Beim Kreis hab ich der Einfachheit halber die fRadius von fx/fy abgezogen bzw. hinzugefügt. Das
ist falsch. Der Kreis wird dabei zu groß gezeichnet.)

Code: Alles auswählen

implementation

{ TKreis }

procedure TKreis.Draw(Canvas: TCanvas);
begin
  // Das ist falsch, damit wird der Kreis zu groß gezeichnet. Aber so ist es einfacher
  Canvas.Ellipse(fx - fRadius, fy - fRadius, fx + fRadius, fy + fRadius);
end;

{ TDreieck }

procedure TDreieck.Draw(Canvas: TCanvas);
begin
  Canvas.MoveTo(fx, fy - fHoehe div 2);
  Canvas.LineTo(fx + fBreite div 2, fy + fHoehe div 2);
  Canvas.LineTo(fx - fBreite div 2, fy + fHoehe div 2);
  Canvas.LineTo(fx, fy - fHoehe div 2);
end;

{ TEllipse }

procedure TEllipse.Draw(Canvas: TCanvas);
begin
 Canvas.Ellipse(fx - fBreite div 2, fy - fHoehe div 2, fx + fBreite div 2, fy + fHoehe div 2);
end;

{ TRechteck }

procedure TRechteck.Draw(Canvas: TCanvas);
begin
  Canvas.RectAngle(fx - fBreite div 2, fy - fHoehe div 2, fx + fBreite div 2, fy + fHoehe div 2);
end;
Bei jedem ordentlichen CAD Programm bemerkt daß Programm, wenn sich was geändert hat und fragt den Anwender ob die Änderungen gespeichert werden sollen.
Ganz soweit werden wir im nächsten Artikel nicht kommen. Aber bemerken werden wir.

Antworten