![]() |
Klasse im Array speichern -> Fehlermeldung
Hallo , ich wollte im Rahmen unseres Unterrichtes eine Oberklasse in einen Array speichern , damit ich dann z.B Feld 3 auswähle , ein Rechteck gezeichnet wird , aber ich bekomme eine Fehlermeldung , sobald ich das in einen Array implentieren will:
Delphi-Quellcode:
Danke schon im Voraus
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; type TForm1 = class(TForm) Button1: TButton; PaintBox1: TPaintBox; Edit1: TEdit; Edit2: TEdit; Label1: TLabel; Label2: TLabel; Button2: TButton; Edit3: TEdit; Edit4: TEdit; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); // procedure AddtoArray; private { Private-Deklarationen } public { Public-Deklarationen } end; Tgeo_objects = class end; Tpunkt = class(Tgeo_objects) x :integer; y:integer; procedure setx(r:integer); procedure sety(z:integer); end; TLinie = class(Tpunkt) p1,p2:Tpunkt; end; TViereck = class(TLinie) protected procedure zeichne; end; TDreieck = class(Tviereck) procedure Dreieckzeichnen; end; Tgeo_objectsArray = Array of Tgeo_objects; var Form1: TForm1; MyViereck : TViereck; Punkt:Tpunkt; r:integer; z:integer; GeoArray :Tgeo_objectsarray; i :integer; Mydreieck:Tdreieck; implementation procedure AddToArray(GeoObject: Tgeo_objects); begin SetLength(Tgeo_objectsArray, Length(Tgeo_objectsArray + 1)); // Fehlermeldung Tgeo_objectsArray[High(Tgeo_objectsArray)] := GeoObject; // Fehlermeldung end; // Fehlermeldung : {[Fehler] Unit1.pas(86): '(' erwartet, aber ',' gefunden [Fehler] Unit1.pas(86): '(' erwartet, aber '+' gefunden [Fataler Fehler] Project1.dpr(5): Verwendete Unit 'Unit1.pas' kann nicht compiliert werden } //Hab die Klammern komplett neugeschrieben , kriege trotzdem den Fehler , was ist das für ein //blöder Fehler ? procedure TViereck.zeichne; begin form1.PaintBox1.Canvas.MoveTo(myviereck.x,myviereck.y); form1.paintbox1.canvas.LineTo(myviereck.x+100,myviereck.y); form1.paintbox1.canvas.lineto(myviereck.x+100,myviereck.y+100); form1.paintbox1.canvas.lineto(myviereck.x,myviereck.y+100); form1.paintbox1.Canvas.MoveTo(myviereck.x,myviereck.y); form1.PaintBox1.canvas.LineTo(myviereck.x,myviereck.y+100); end; procedure TPunkt.Setx(r:integer); begin x:=r; end; procedure TPunkt.sety(z:integer); begin y:=z; end; procedure TDreieck.Dreieckzeichnen; begin form1.PaintBox1.Canvas.MoveTo(mydreieck.x,mydreieck.y); form1.PaintBox1.Canvas.LineTo(mydreieck.x+100,mydreieck.y); form1.PaintBox1.Canvas.MoveTo(mydreieck.x,mydreieck.y); form1.paintbox1.canvas.LineTo(mydreieck.x,mydreieck.y+100); form1.paintbox1.Canvas.MoveTo(mydreieck.x,mydreieck.y+100); form1.PaintBox1.Canvas.LineTo(mydreieck.x+100,mydreieck.y); end; {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin MyViereck := TViereck.Create; r:= strtoint(edit1.text); z:= strtoint(edit2.text); myviereck.setx(r); myviereck.sety(z); MyViereck.zeichne; MyViereck.Free; end; procedure TForm1.Button2Click(Sender: TObject); begin r := strtoint(edit3.text); z := strtoint(edit4.text); Mydreieck := Tdreieck.Create; mydreieck.setx(r); mydreieck.sety(z); mydreieck.Dreieckzeichnen; mydreieck.Free end; end. |
AW: Klasse im Array speichern -> Fehlermeldung
Du willst ja nicht im Typ Tgeo_objectsArray, sondern in der Variablen GeoArray speichern.
|
AW: Klasse im Array speichern -> Fehlermeldung
Delphi-Quellcode:
Du solltest die Klammern richtig setzen, und den Variablennamen benutzen und nicht die Typenbezeichnung.
procedure AddToArray(GeoObject: Tgeo_objects);
begin SetLength(GeoArray, Length(GeoArray) + 1); // Fehlermeldung GeoArray[High(GeoArray)] := GeoObject; // Fehlermeldung end; Grüße Klaus |
AW: Klasse im Array speichern -> Fehlermeldung
Die Lösung wurde schon verraten, aber dennoch:
Zitat:
- GeoArray würde ganz gut in das PRIVATE der Form passen - und der Rest sind eigentlich nur lokale Variablen, welche z.B. jeweils in die Button-Klick-Methoden gehören Und warum greifen TDreieck und Co. direkt auf Form1 zu? |
AW: Klasse im Array speichern -> Fehlermeldung
Zitat:
|
AW: Klasse im Array speichern -> Fehlermeldung
Und generell bringt dir das mit dem Array auch nicht viel, ausser, dass du die Instanzen dort speichern kannst.
Doch bei jedem Zugriff musst du immer erst den Typ ermitteln, um mit der Instanz etwas anstellen zu können. Das ist nicht so wirklich OOP ;) Aber darauf haben wir ja schon mehrmals hingewiesen, allerdings sehe ich in deinen Klassendefinitionen niemals eine Veränderung. Hier nochmal ein letzter Versuch:
Delphi-Quellcode:
Der Gewinn hierbei ist:
type
// Tgeo_objects = class // Jede Ableitung muss diese procedure überschreiben (override) procedure Zeichne( aCanvas : TCanvas ); virtual; abstract; end; Tgeo_objects_array = array of Tgeo_objects; TPunkt = class( Tgeo_objects ) x, y : integer; // Zeichnen eines Punkts procedure Zeichne( aCanvas : TCanvas ); override; end; TLinie = class( Tgeo_objects ) p1, p2 : TPunkt; // Zeichnen einer Linie procedure Zeichne( aCanvas : TCanvas ); override; end; TRechteck = class( Tgeo_objects ) p1, p2 : TPunkt; // Zeichnen eines Rechtecks procedure Zeichne( aCanvas : TCanvas ); override; end; implementation procedure TPunkt.Zeichne( aCanvas : TCanvas ); begin // Hier jetzt auf den übergebenen Canvas (aCanvas) malen end; procedure TLinie.Zeichne( aCanvas : TCanvas ); begin // Hier jetzt auf den übergebenen Canvas (aCanvas) malen end; procedure TRechteck.Zeichne( aCanvas : TCanvas ); begin // Hier jetzt auf den übergebenen Canvas (aCanvas) malen end;
Delphi-Quellcode:
Abhängig von der Instanz im Array, wird so automatisch immer die zugehörige Methode Zeichne aufgerufen
procedure TForm1.BtnZeichneArray( Sender : TObject );
var idx : integer; begin // Jedes Element im Array wird nun gezeichnet und zwar auf // dem Canvas der aktuellen Form-Instanz (Self.Canvas oder einfach Canvas) for idx := Low( GeoArray ) to High( GeoArray ) do GeoArray[ idx ].Zeichne( {Self.}Canvas ); end; |
AW: Klasse im Array speichern -> Fehlermeldung
Zitat:
Und die Codeformatierung hab ich mal nicht erwähnt. |
AW: Klasse im Array speichern -> Fehlermeldung
Wäre es hier nicht besser eine TObjectList zu nehmen? Dann könnte man sich das SetLength sparen und wenn er später mal ein Elemet entfernen möchte, brauch er nur Delete zu nehmen.
|
AW: Klasse im Array speichern -> Fehlermeldung
Vielen Dank für die Antworten.
Ich weiß , dass das nicht sooo OOP ist. Aber das was mir vorgeschlagen wird , mit Überschreiben abstract , virtual etc. Das KENNE ich doch garnicht ? Das haben wir im Unterricht noch nie behandelt , ich kann ja nix anwenden , was ich noch nicht hatte. Klar , ich kanns raufklatschen und dann compilieren , kein Ding , aber ich will ja nachvollziehen und verstehen , was da gemacht wird. Versteht ihr ? |
AW: Klasse im Array speichern -> Fehlermeldung
Hier ist eine "Basis"-Klasse, welche eine überschreibbare Methode enthält:
Delphi-Quellcode:
Wenn der Vorfahr noch keine Implementation dieser Methode benötigt, dann kann man sie abstact deklatieren.
type
TVorfahr = class procedure MachWas; procedure MachNochwas; virtual; end; procedure TVorfahr.MachWas; begin ShowMessage('ich bin MachWas von TVorfahr'); end; procedure TVorfahr.MachNochwas; begin ShowMessage('ich bin MachNochwas von TVorfahr'); end; (es befindet sich dann "noch" kein Code in dieser Methode)
Delphi-Quellcode:
Ein Nachfahr kann nun diese Methode mit neuem Code überschreiben.
type
TVorfahr2 = class procedure MachWas; procedure MachNochwas; virtual; abstract; end; procedure TVorfahr2.MachWas; begin ShowMessage('ich bin MachWas von TVorfahr2'); end;
Delphi-Quellcode:
Oder diese Methode wird ergänzt/erweitert, indem der Code des Vorfahren mit aufgerufen (inherited) wird.
type
TNachfahr = class(TVorfahr) procedure MachNochwas; override; end; procedure TNachfahr.MachNochwas; begin ShowMessage('ich bin MachNochwas von TNachfahr'); end;
Delphi-Quellcode:
Jenachdem welche Klasse nun erstellt wurde, kann man über die selbe Schnittstelle (hier die von TVorfahr) irgendeine Methode aufrufen, welche von einem Nachfahren überschrieben wurde.
type
TAndererNachfahr = class(TVorfahr) procedure MachNochwas; override; end; procedure TNachfahr.MachNochwas; begin inherited; ShowMessage('ich bin MachNochwas von TNachfahr'); end;
Delphi-Quellcode:
Dem Code ist es also egal, ob und welcher Nachfahre verwentet wurde, da alle wichtigen Schnittstellen schon im Vorfahren existiert, welche man nun problemlos aufrufen kann.
var
X: TVorfahr; ShowMessage('jetzt kommt TVorfahr'); X := TVorfahr.Create; try X.MachWas; X.MachNochwas; finally X.Free; end; ShowMessage('jetzt kommt TNachfahr'); X := TNachfahr.Create; try X.MachWas; X.MachNochwas; finally X.Free; end; ShowMessage('jetzt kommt TAndererNachfahr'); X := TAndererNachfahr.Create; try X.MachWas; X.MachNochwas; finally X.Free; end; ShowMessage('jetzt ist Schluß'); Hier der Beweis:
Delphi-Quellcode:
(statt der MessageBox, könnte man den Text auch in ein Memo schreiben)
var
X: TVorfahr; i: Integer; for i := 0 to 2 do begin case i of 0: begin ShowMessage('jetzt kommt TVorfahr'); X := TVorfahr.Create; end; 1: begin ShowMessage('jetzt kommt TNachfahr'); X := TNachfahr.Create; end; 2: begin ShowMessage('jetzt kommt TAndererNachfahr'); X := TAndererNachfahr.Create; end; end; try X.MachWas; X.MachNochwas; finally X.Free; end; end; ShowMessage('jetzt ist Schluß'); |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:25 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