Einzelnen Beitrag anzeigen

Benutzerbild von Jelly
Jelly

Registriert seit: 11. Apr 2003
Ort: Moestroff (Luxemburg)
3.741 Beiträge
 
Delphi 2007 Professional
 
#9

Re: Liste verschiedener Klassen

  Alt 15. Apr 2007, 12:35
Zitat von Antigo:
Könnte ich also beispielsweise eine Klasse TOberKlase definienieren, dort vorgeben, dass es eine zeichnen prozedur geben soll, und dann nachher die Instanzen die in der TObjectliste sind so behandeln als wären sie Instanzen der TOberklasse?
Yup, genau das nennt man Polymorphismus.

Hier mal schnell ein Beispiel:
Delphi-Quellcode:
unit Unit25;

interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TFigur = class
  private
    FCanvas: TCanvas;
    FColor: TColor; // TOberklasse
  public
     procedure Zeichnen ; virtual ;
  public
     constructor Create (ACanvas : TCanvas) ;
     property Canvas : TCanvas read FCanvas ;
     property Color : TColor read FColor write FColor ;
  end;

  TKreis = class (TFigur)
  private
    FRadius: integer;
    FMittelpunkt: TPoint;
  public
    procedure Zeichnen ; override ;
    property Mittelpunkt : TPoint read FMittelpunkt write FMittelpunkt ;
    property Radius : integer read FRadius write FRadius ;
  end;

  TRechteck = class (TFigur)
  private
    FRect: TRect;
  public
    procedure Zeichnen ; override ;
    property Rect : TRect read FRect write FRect ;
  end;



implementation

{ TKreis }

procedure TKreis.Zeichnen;
begin
     inherited ;
     Canvas.Ellipse(Mittelpunkt.x - Radius div 2, Mittelpunkt.Y - Radius div 2,
                    Mittelpunkt.x + Radius div 2, Mittelpunkt.Y + Radius div 2) ;
end;

{ TFigur }

constructor TFigur.Create(ACanvas: TCanvas);
begin
     inherited Create ;
     FCanvas := ACanvas ;
end;

procedure TFigur.Zeichnen;
begin
     Canvas.Pen.Color := Color ;
     Canvas.Pen.Style := psSolid ;
     Canvas.Pen.Width := 2 ;
end;

{ TRechteck }

procedure TRechteck.Zeichnen;
begin
     inherited ;
     Canvas.Rectangle(Rect);
end;

end.
Die Oberklasse heisst TFigur, und beherbergt schon einige gemeinsame Dinge wie Color und Canvas. Und bereits eine Methode Zeichnen, in der die Farbe von Pen gesetzt wird. Aber diese Methode in TFigur weiss natürlich nicht, wie sich ein Kreis zeichnet und wie ein Rechteck. Die weiss noch nicht einmal, dass es sowas gibt.

Wenn du aber jetzt eine Instanz von TKreis erstellst, und eine von TRechteck, wie folgt:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  Liste : TObjectList ;
  obj : TFigur ;
  i: Integer;
begin
     Liste := TObjectList.Create ;
     obj := TKreis.Create(self.canvas);
     obj.Color := clRed ;
     (obj as TKreis).Mittelpunkt := Point (80,80) ;
     (obj as TKreis).Radius := 30 ;
     Liste.Add(obj) ;

     obj := TRechteck.Create(self.canvas);
     obj.Color := clGreen ;
     (obj as TRechteck).Rect := Rect (100,100,130,130) ;
     Liste.Add(obj) ;

     for i := 0 to Liste.Count - 1 do
         (Liste[i] as TFigur).Zeichnen; // hier passiert das Magische
end;
Merke, dass obj as TFigur deklariert ist.
Und in der letzten Zeile wird gezeichnet. Und zwar wir über
Liste[i] as TFigur gecastet. Und nicht etwas über TKreis oder TRechteck. Es ist irrelevant, welcher Abkömmling wirklich im Objekt steckt. Da die Zeichnen-Methode in TFigur virtuell ist, und die Zeichnen-Methoden in TKreis und TRechteck ein inherited aufrufen, wird dadurch zur Laufzeit die korrekte Zeichnen Methode übernommen. Genau das ist Polymorphismus.
  Mit Zitat antworten Zitat