Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Liste verschiedener Klassen (https://www.delphipraxis.net/90286-liste-verschiedener-klassen.html)

Antigo 14. Apr 2007 17:59


Liste verschiedener Klassen
 
Hi,
ich bin grad bei der Planung eines neuen Projektes.

Hier habe ich jetzt Objekte verschiedener Klassen, die ich in einer Liste/Array speichern will.

Index | Klasse
0 | TKLasse1
1 | TKlasse2
2 | TKLasse3
3 | TKlasse2

Diese Liste von Objekten verschiedener Klassen will ich jetzt visualisieren. Dafür bekommt jede Klasse eine Prozedur die es auf eine Paintbox zeichnen lässt, so dass ich mit einer for Schleife alle Objekte zeichnen kann.

Erste Frage, wie speichere ich die Objekte? nehme ich ein array of TObject? Wie kriege ich dann raus von welcher Klasse das aktuelle Objekt eine Instanz ist?

Ich hoffe es wird klar was ich meine. Ich hab eine Liste von Items, die alle verschiedenen Types ist, und die will ich irgendwie unter einen Hut bringen.

Vielen Dank schonmal für eure Hilfe.

mfg

cruiser 14. Apr 2007 18:11

Re: Liste verschiedener Klassen
 
Eine TObjectList aus der Unit Contnrs sollte genau das richtige sein

ggf. kannst du die auch ableiten/wrappen um deine Zeichenmethoden gleich einzubauen

Antigo 14. Apr 2007 20:09

Re: Liste verschiedener Klassen
 
wie komme ich denn dann an den Typ des Objekts? Muss ich jedesmal abfragen if instanz is TKlasse?

St.Pauli 14. Apr 2007 20:14

Re: Liste verschiedener Klassen
 
Leite die Klassen von TPersistent ab und benutze die Funktion GetNamePath(). Hab leider keine Delphi-IDE zur Hand um es zu testen, müsste aber gehen... ;)

Antigo 14. Apr 2007 20:46

Re: Liste verschiedener Klassen
 
Zitat:

TPersistent ist der Vorfahr aller Objekte, die über Zuweisungs- und Stream-Funktionen verfügen.
Bist du sicher, dass das das richtige (omg 3 das) für mich ist? Ich brauche eigentlich keine stream funktionen.

trotzdem schonmal danke für den tipp :)

Hawkeye219 14. Apr 2007 20:47

Re: Liste verschiedener Klassen
 
Hallo Michael,

schaue dir doch einmal dieses Tutorial an, bevor du dein Projekt startest. Insbesondere die Kapitel Vererbung und Polymorphie könnten sehr hilfreich sein.

Gruß Hawkeye

Antigo 14. Apr 2007 20:59

Re: Liste verschiedener Klassen
 
Zitat:

Zitat von Hawkeye219
Hallo Michael,

schaue dir doch einmal dieses Tutorial an, bevor du dein Projekt startest. Insbesondere die Kapitel Vererbung und Polymorphie könnten sehr hilfreich sein.

Gruß Hawkeye

Vielen Dank für den link.

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?
also
Delphi-Quellcode:
for i:=0 to objectliste.count-1 do
  (objectliste[i] as TOberklasse).zeichnen
Obwohl es zum Biespiel Instanzen der TKlasse1 sind, die aber von TOberklasse abgeleitet ist?

mkinzler 14. Apr 2007 21:01

Re: Liste verschiedener Klassen
 
Ja, denn es gilt den Tklasse IS-A TOberklasse.

Jelly 15. Apr 2007 11:35

Re: Liste verschiedener Klassen
 
Zitat:

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
Delphi-Quellcode:
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.


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:53 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz