Autor Beitrag
mtin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 177

Win XP SP2
BDS2006 Enterprise
BeitragVerfasst: Mo 12.12.05 17:42 
ich hab folgendes Problem, wir haben in der Schule jetzt mit der Objektorientierten Programmierung angefangen und da ein Beispiel in C++ bekommen...ich würde das ganze aber gerne in Delphi schreiben und habe nun Probleme alle Objekte (versch. Objekte -> ein array)

dies sind meine 3 Klassen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
type figurC = class
                 x,y:integer;
                public
                 procedure setXY(ortx,orty:integer);
                 procedure getXY(var ortx:integer;var orty:integer);
                 procedure show;
              end;
     quadratC = class(figurC)
                  laenge:integer;
                 public
                  procedure setlaenge(l:integer);
                  procedure show;virtual;
                end;
     circleC = class(figurC)
                  radius:integer;
                 public
                  procedure setradius(r:integer);
                  procedure show;virtual;
                end;

hab also 2 figuren, quadratc und circlec...
(figurC wird nicht benötigt/gezeichnet, dient nur zur Vererbung von n paar dingen)
Diese wollte ich jetzt beide in einem dynamischen Array unterbringen, so dass ich z.b. um alle Kreise und Quadrate zu zeichnen nur eine for-Schleife brauch die von figuren[0] bis figuren[count(figuren)] figuren[i].show; macht...

Hab also versucht den ganzen Spaß zu schreiben, wie die anderen das in C++ gemacht haben:

figuren:array of figurC;

doch irgendwie geht das in Delphi nciht!!! In C++ konnten die einfach dann hinschreiben:

figuren[0] := QuadratC.Create;

soweit meckert Delphi auch noch nicht, allerdings kann ich jetzt in figuren[0].xxxxxx nicht auf die Quadratspeziefischen Funktionen zugreifen, was in C++ nun aber ging!!!!
mein Infoleherer meinte dann noch ich solle das quadrat erst in einer Variable vom typ QuadratC erstellen, und es erst am Ende mit
figuren[0]:= meinequadratvariable;
reinschreiben, aber das ging genausowenig, und außerdem würde ich ja gerne im Nachhinein auf einzelne Elemente des Arrays zugreifen und die jeweiligen speziefischen Einstellungen vornehmen, je nachdem ob da grad ein Kreis oder ein Quadrat an der Stelle gespeichert ist....

ich hoff ma das das einigermaßen verständlich is :D und das das mit delphi möglich is :?
MrSaint
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1033
Erhaltene Danke: 1

WinXP Pro SP2
Delphi 6 Prof.
BeitragVerfasst: Mo 12.12.05 17:47 
Stichwort: SetLength! Du must in dem Array erst mal Speicher reservieren! ALternativ könntest du auch ein statisches Array machen, etwa so:

ausblenden Delphi-Quelltext
1:
variable: array [0..9of figurC;					




MrSaint

_________________
"people knew how to write small, efficient programs [...], a skill that has subsequently been lost"
Andrew S. Tanenbaum - Modern Operating Systems
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 480

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Mo 12.12.05 17:50 
Ins Blaue geraten sollte das hinhauen:
ausblenden Delphi-Quelltext
1:
(figuren[0as QuadratC).laenge;					

_________________
We are, we were and will not be.
mtin Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 177

Win XP SP2
BDS2006 Enterprise
BeitragVerfasst: Mo 12.12.05 17:54 
@MrSaint klar an sowas denkich schon ;)

@Gausi DAS KÖNNTE ES SEIN!!!! jetzt wo dus sagst MUSS es eigentlich so sein :D
ich probiers sofort aus!

EDIT:hm, so ganz geht das noch nicht!!

hier nochmal die Zuweisung, erstmal als extra Varialbe und dann erst in das array geschrieben:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
if RadioButton1.checked=true then
begin
  meinQuadrat:=QuadratC.Create;
  meinQuadrat.setlaenge(strtoint(Edit3.text));
  meinQuadrat.setXY(strtoint(Edit1.Text),strtoint(Edit2.Text));
  ListBox1.Items.Add(IntToStr(length(figuren))+'. Quadrat');

  figuren[length(figuren)-1]:=meinQuadrat;

  end;
if RadioButton2.checked=true then
begin
  meinKreis:=circleC.Create;
  meinKreis.setradius(strtoint(Edit3.text));
  meinKreis.setXY(strtoint(Edit1.Text),strtoint(Edit2.Text));
  ListBox1.Items.Add(IntToStr(length(figuren))+'. Kreis');

  figuren[length(figuren)-1]:=meinKreis;
end


doch wie zeige ich die jetzt alle an?
bei dem hier kommen leicht viele Fehlermeldungen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
for i:=0 to (length(figuren)-1do
 begin
 (figuren[i] as QuadratC).show;
 (figuren[i] as CircleC).show;
 end;

aber das geht genausowenig (wird gar nix angezeigt)
ausblenden Delphi-Quelltext
1:
2:
3:
4:
for i:=0 to (length(figuren)-1do
 begin
 figuren[i].show;
 end;
Stefan.Buchholtz
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 612

WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
BeitragVerfasst: Mo 12.12.05 18:37 
Deine Prozedurdeklarationen sind falsch - Funktionen, die man überschreiben können soll, müssen in der Basisklasse mit virtual deklariert werden und in abgeleiteten Klassen als override. So ist es richtig:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
type Tfigur = class  
                 x,y:integer;  
                public  
                 procedure setXY(ortx,orty:integer);  
                 procedure getXY(var ortx:integer;var orty:integer);  
                 procedure show; virtualabstract;
              end;  
     Tquadrat = class(Tfigur)  
                  laenge:integer;  
                 public  
                  procedure setlaenge(l:integer);  
                  procedure show;override;  
                end;  
     Tcircle = class(Tfigur)  
                  radius:integer;  
                 public  
                  procedure setradius(r:integer);  
                  procedure show; override;                
                end;


Der Aufruf von Show geht dann mit

ausblenden Delphi-Quelltext
1:
figuren[0].Show;					


und es wird abhängig davon ob es nun ein TCircle oder TQuadrat ist das richtige Show aufgerufen. Ich habe Tfigur.show noch als abstract gekennzeichnet, das bedeutet, dass es in Tfigur keine Implementation davon gibt, sondern erst in abgeleiteten Klassen.

Zugriff auf nicht in der Basisklasse enthaltene Prozeduren funktioniert mit einem Cast:

ausblenden Delphi-Quelltext
1:
(figur[0as Tquadrat).setlaenge(10);					


Das musst du so machen, weil SetLaenge in Tfigur nicht enthalten ist.

ausblenden Delphi-Quelltext
1:
figur[0].setlaenge(10);					


führt deswegen zu einem Compilerfehler. Das ist meines Wissens aber in C++ genauso.
In Delphi ist es übrigens Konvention, Klassennamen mit einem grossen T zu beginnen, deswegen habe ich das hier mal so gemacht.

Stefan

_________________
Ein Computer ohne Windows ist wie eine Schokoladentorte ohne Senf.
mtin Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 177

Win XP SP2
BDS2006 Enterprise
BeitragVerfasst: Mo 12.12.05 23:03 
ok danke, das war schonmal sehr Hilfreich!
und...du glaubst es nich...es funktioniert :D

eine nächste frage wäre: wie finde ich heraus ob nun ein Kreis oder ein Quadrat in figuren[i] ist?
das einzige was mir dazu einfallen würde wäre das ausprobieren und mit try..except den Fehler abfangen...aber gibts da ne schönere Möglichkeit?
MagicAndre1981
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 12.12.05 23:13 
Ich werfe mal das Wort Collections in den Raum.

Du sagst OOP und fummelst mit Arrays rum :shock:

Hier gibts was schönes: www.delphipraxis.net/topic28945.html

www.delphipraxis.net...ur+dpcollection.html


André
Stefan.Buchholtz
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 612

WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
BeitragVerfasst: Di 13.12.05 11:13 
user profile iconmtin hat folgendes geschrieben:
ok danke, das war schonmal sehr Hilfreich!
und...du glaubst es nich...es funktioniert :D

eine nächste frage wäre: wie finde ich heraus ob nun ein Kreis oder ein Quadrat in figuren[i] ist?
das einzige was mir dazu einfallen würde wäre das ausprobieren und mit try..except den Fehler abfangen...aber gibts da ne schönere Möglichkeit?


Das kannst du mit dem is-Operator machen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
if figuren[i] is Tquadrat then
begin
  Tquadrat(figuren[i]).setlaenge(10);
  ...


Stefan

_________________
Ein Computer ohne Windows ist wie eine Schokoladentorte ohne Senf.
Stefan.Buchholtz
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 612

WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
BeitragVerfasst: Di 13.12.05 11:22 
user profile iconMagicAndre1981 hat folgendes geschrieben:
Ich werfe mal das Wort Collections in den Raum.

Du sagst OOP und fummelst mit Arrays rum :shock:

Hier gibts was schönes: www.delphipraxis.net/topic28945.html

www.delphipraxis.net...ur+dpcollection.html


Okay, aber da braucht man wieder extra Bibliotheken, weil Delphi (zumindest Delphi 7, Win32) nicht wirklich gut mit Collections ausgestattet ist. Java oder .NET sind da wesentlich besser gerüstet. Wir haben hier für interne Verwendung auch ein paar Collection-Klassen geschrieben.
Manchmal ist aber ein gutes altes Array auch die beste Lösung - wenn man weiss, wie viele Objekte man hat und nur über Index drauf zugreifen will, ist eine Collection-Klasse nur unnötiger Overhead.

Stefan

_________________
Ein Computer ohne Windows ist wie eine Schokoladentorte ohne Senf.