Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Klasse im Array speichern -> Fehlermeldung (https://www.delphipraxis.net/166278-klasse-im-array-speichern-fehlermeldung.html)

hotkey 6. Feb 2012 09:53

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:
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.
Danke schon im Voraus

DeddyH 6. Feb 2012 09:56

AW: Klasse im Array speichern -> Fehlermeldung
 
Du willst ja nicht im Typ Tgeo_objectsArray, sondern in der Variablen GeoArray speichern.

Klaus01 6. Feb 2012 09:58

AW: Klasse im Array speichern -> Fehlermeldung
 
Delphi-Quellcode:
procedure AddToArray(GeoObject: Tgeo_objects);
begin
  SetLength(GeoArray, Length(GeoArray) + 1); // Fehlermeldung
  GeoArray[High(GeoArray)] := GeoObject; // Fehlermeldung
end;
Du solltest die Klammern richtig setzen, und den Variablennamen benutzen und nicht die Typenbezeichnung.

Grüße
Klaus

himitsu 6. Feb 2012 10:09

AW: Klasse im Array speichern -> Fehlermeldung
 
Die Lösung wurde schon verraten, aber dennoch:

Zitat:

Delphi-Quellcode:
  MyViereck : TViereck;
  Punkt:Tpunkt;
  r:integer;
  z:integer;
  GeoArray :Tgeo_objectsarray;
  i :integer;
  Mydreieck:Tdreieck;

Warum sind diese Variablen global?
- 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?

DeddyH 6. Feb 2012 10:12

AW: Klasse im Array speichern -> Fehlermeldung
 
Zitat:

...ich wollte im Rahmen unseres Unterrichtes...
Noch Fragen?

Sir Rufo 6. Feb 2012 10:17

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:
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;
Der Gewinn hierbei ist:
Delphi-Quellcode:
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;
Abhängig von der Instanz im Array, wird so automatisch immer die zugehörige Methode Zeichne aufgerufen

himitsu 6. Feb 2012 10:21

AW: Klasse im Array speichern -> Fehlermeldung
 
Zitat:

Zitat von DeddyH (Beitrag 1149426)
Noch Fragen?

Deswegen ja ... damit er und eventuell auch die Anderen und vorallem der Lehrer mal drüber nachdenken. :angle2:
Und die Codeformatierung hab ich mal nicht erwähnt.

MW97 7. Feb 2012 18:06

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.

hotkey 8. Feb 2012 13:36

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 ?

himitsu 8. Feb 2012 14:50

AW: Klasse im Array speichern -> Fehlermeldung
 
Hier ist eine "Basis"-Klasse, welche eine überschreibbare Methode enthält:
Delphi-Quellcode:
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;
Wenn der Vorfahr noch keine Implementation dieser Methode benötigt, dann kann man sie abstact deklatieren.
(es befindet sich dann "noch" kein Code in dieser Methode)
Delphi-Quellcode:
type
  TVorfahr2 = class
    procedure MachWas;
    procedure MachNochwas; virtual; abstract;
  end;

procedure TVorfahr2.MachWas;
begin
  ShowMessage('ich bin MachWas von TVorfahr2');
end;
Ein Nachfahr kann nun diese Methode mit neuem Code überschreiben.
Delphi-Quellcode:
type
  TNachfahr = class(TVorfahr)
    procedure MachNochwas; override;
  end;

procedure TNachfahr.MachNochwas;
begin
  ShowMessage('ich bin MachNochwas von TNachfahr');
end;
Oder diese Methode wird ergänzt/erweitert, indem der Code des Vorfahren mit aufgerufen (inherited) wird.
Delphi-Quellcode:
type
  TAndererNachfahr = class(TVorfahr)
    procedure MachNochwas; override;
  end;

procedure TNachfahr.MachNochwas;
begin
  inherited;
  ShowMessage('ich bin MachNochwas von TNachfahr');
end;
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.
Delphi-Quellcode:
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ß');
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.
Hier der Beweis:
Delphi-Quellcode:
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ß');
(statt der MessageBox, könnte man den Text auch in ein Memo schreiben)


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:46 Uhr.
Seite 1 von 2  1 2      

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