Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Tutorials und Kurse (https://www.delphipraxis.net/36-tutorials-und-kurse/)
-   -   Delphi Klassen in Delphi (https://www.delphipraxis.net/16557-klassen-delphi.html)

Luckie 19. Feb 2004 04:41


Klassen in Delphi
 
Liste der Anhänge anzeigen (Anzahl: 2)
Klassen in Delphi
Thema: Einführung in die objektorientierte Programmierung mit Delphi
Datum: 2007-12-02

Das Tutorial wurde - im Zuge der Vereinheitlichung der Layouts meiner PDF-Dokumente - noch mal neu mit Latex geschrieben. Inhaltlich hat sich nichts geändert. Das Layout ist jetzt doppelseitig und kann so schön ausgedruckt und gebunden werden (falls das jemand machen sollte ;) ).

Das Tutorial liegt als PDF vor und kann hier: http://delphitutorials.michael-puff.de runtergeladen bzw. online eingesehen werden. In dem dazugehörigen Zip Archiv (Klassen_in_Delphi.zip) befinden sich noch zusätzlich Demos.

2007-12-02:
Kapitel "Sichtbarkeiten" ünberarbeitet.
Anhang mit Interans zum Konstruktor, Destruktor und Methodenzeigern von Andreas Hausladen.

Pseudemys Nelsoni 19. Feb 2004 07:00

Re: Klassen in Delphi
 
Sieht gut aus(auch wenn ich noch nicht bei klassen bin), ausführlich geschrieben. Gut gemacht Luckie :thuimb: .

Ich wollte einen (in meinen augen) kleinen (schreib)-fehler bemerken

Zitat:

Eine Methode ist eine Prozedur oder Funktion, die zu einer Klasse gehören
Müsste "gehört" heissen 8)

Jens Schumann 19. Feb 2004 07:05

Re: Klassen in Delphi
 
Hallo Luckie,
vielen Dank für das Tutorial.
Das Beispiel auf Seite 10 kann ich nicht nachvollziehen

Delphi-Quellcode:
...
  Figure := TFigure.Create;
  try
   TRectangle(Figure).Draw('TFigure.Create / TRectangle(Figure).Draw');
                   // Ruft TRectangle.Draw auf
  finally
    FreeAndNil(Figure);
    end;
...
Hier wird nicht TRectangle.Draw sondern TFigure.Draw aufgerufen. Wenn Figure vom Type TFigure ist und als TFigure instanziert wird kann trotz Typcast nur TFigure.Draw aufgerufen werden.
Wenn Figure vom Type TFigure ist und als TRectangle instanziert wird sieht die Sache schon ganz anders aus.
Delphi-Quellcode:
var
  Figure : TFigure;
begin
  Figure:=TRectangle.Create;
  Try
    Figure.Draw('TFigure.Create / TRectangle(Figure).Draw');
  Finally
    Figure.Free;
    end;
end;

Luckie 19. Feb 2004 08:59

Re: Klassen in Delphi
 
Delphi-Quellcode:
  Figure := TFigure.Create;
  try
    TRectangle(Figure).Draw('TFigure.Create / TRectangle(Figure).Draw');
      // Ruft TRectangle.Draw auf
  finally
    FreeAndNil(Figure);
  end;
Kuck es dir im Demo an. Setz einen Breakpunkt auf Figure := TFigure.Create und gehe mit F7 durch und kuck welche Methode er aufruft. Bei mir springt er in die Draw Methode von TRectangle. ;) Ist ja auch logisch, sonst wäre der Cast ja Blödsinn.

sakura 19. Feb 2004 09:07

Re: Klassen in Delphi
 
Zitat:

Zitat von Luckie
Delphi-Quellcode:
  Figure := TFigure.Create;
  try
    TRectangle(Figure).Draw('TFigure.Create / TRectangle(Figure).Draw');
      // Ruft TRectangle.Draw auf
  finally
    FreeAndNil(Figure);
  end;

Das ist zwar ein Beispiel für das casten und ich gehe mal davon aus, daß TRectangle von TFigure abgeleitet ist, allerdings sollte man nie ein Objekt auf eine Klasse casten, von der es nicht abstammt - imho ein Negativbeispiel für das Verständnis von Klassen!

...:cat:...

Luckie 19. Feb 2004 09:14

Re: Klassen in Delphi
 
Zitat:

Zitat von sakura
allerdings sollte man nie ein Objekt auf eine Klasse casten, von der es nicht abstammt

TRectangle ist ein Nachfahre von TFigure. Insofern tue ich, laut deinen Worten nichts verbotenes. Wirf auch dies bezüglich mal einen Blick in den Handbuchsatz und kuck dir da das Beispiel an. ;)

sakura 19. Feb 2004 09:23

Re: Klassen in Delphi
 
Zitat:

Zitat von Luckie
TRectangle ist ein Nachfahre von TFigure. Insofern tue ich, laut deinen Worten nichts verbotenes. Wirf auch dies bezüglich mal einen Blick in den Handbuchsatz und kuck dir da das Beispiel an. ;)

Danke für Die Info, also Sprachreferenz 7-11, auch da steht:

Delphi-Quellcode:
Figure := TRectangle.Create;
und nicht

Delphi-Quellcode:
Figure := TFigure.Create;
...:cat:...

Jens Schumann 19. Feb 2004 09:24

Re: Klassen in Delphi
 
Hallo Luckie,
ich habe nicht gesehen, dass es um statische Methoden geht.
Wenn die Methoden virtual / override sind funktioniert Dein Beispiel nicht so
wie beschrieben.
Warum es mit statischen Methode funktioniert weiss ich nicht.

Eigentlich müsste der Compiler das ablehnen. Du erzeugst eine Instanz von TFigure und sagst dem Compiler über den Cast es handelt sich um eine Instanz von TRectangle. Es handelt sich hier mehr
um ein Gefühl. D.h. ich würde mich sehr unwohl bei so einer Sache fühlen. Deshalb habe ich sowas wahrscheinlich auch noch nicht gemacht (so rein intuitiv). Ich versuche es mal mit einem Beispiel:
Delphi-Quellcode:
var
 aObj : TObject;
 aFrm : TForm;
...
 aObj:=aFrm; // Ok kein Problem
 aFrm:=aObj; // Compiler meckert zu recht
Wobei ich das Gefühl habe, dass Dein TRectangle(Figure).Draw hier im Beispiel dem aFrm:=aObj entspricht.

neolithos 19. Feb 2004 09:30

Re: Klassen in Delphi
 
Zitat:

Zitat von Jens Schumann
Delphi-Quellcode:
aFrm:=TForm(aObj);

Sind eh alles bloß Zeiger auf Instanzen.

Ist aObj kein TForm-Nachfahre, meckert er erst wenn du versuchst eine Methode aufzurufen!

Luckie 19. Feb 2004 09:35

Re: Klassen in Delphi
 
Nein, ich hatte mich vertan, Das war etwas unübersichtlich in dem Beispiel in dem Buch. Ich habe es schon korrigiert, auch das Demo.

sakura 19. Feb 2004 09:37

Re: Klassen in Delphi
 
Liste der Anhänge anzeigen (Anzahl: 1)
Also ich habe auch ein wenig gelernt. Fakt ist aber, das nicht TRectangle.Draw aufgerufen wird, wenn das Objekt mit TFigure.Create aufgerufen wurde, sondern TFigure.Draw ;-) Ich hätte im schlimmsten Fall eine AV erwartet :mrgreen:

Anbei ein kleines Beispiel, das den obigen Umstand näher betrachtet.

...:cat:...

Jens Schumann 19. Feb 2004 09:52

Re: Klassen in Delphi
 
Hallo,
das hat mein Weltbild zerstört.
Delphi-Quellcode:
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

type
  TFigure = class(TObject)
    procedure Draw(Caption: string);
  end;

  TRectangle = class(TFigure)
    procedure Draw(Caption: string);
    procedure Show(Caption : String);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TFigure.Draw(Caption: string);
begin
  Messagebox(0, 'Draw Methode von TFigure', @Caption[1], 0);
end;

procedure TRectangle.Draw(Caption: string);
begin
  Messagebox(0, 'Draw Methode von TRectangle', @Caption[1], 0);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Figure: TFigure;
  Rectangle: TRectangle;
  aObj      : TObject;
begin
  ...
  Figure := TFigure.Create;
  try
    TRectangle(Figure).Show('TFigure.Create / TRectangle(Figure).Draw');
      // Show nicht in TFigure trotzdem wird aber TRectangle.Show aufgerufen.
   finally
    FreeAndNil(Figure);
  end;
  ...
end;

procedure TRectangle.Show(Caption: String);
begin
  Messagebox(0, 'Show Methode von TRectangle', @Caption[1], 0);
end;

end.
Das ist nicht zu fassen obwohl Show keine Methode von TFigure ist, wird durch den Cast TRectangle.Show aufgerufen.
Hat jemand dafür eine Erklärung ?

Chewie 19. Feb 2004 10:22

Re: Klassen in Delphi
 
Die Delphi-Hilfe sagt zu statischen Methoden:

Zitat:

Beim Aufruf bestimmt der deklarierte Typ (also der Typ zur Compilierzeit) der im Aufruf verwendeten Klassen- bzw. Objektvariable, welche Implementierung aktiviert wird.
D.h. im Compilat steht gar nix von TFigure.Draw, sondern es wird einfach die Methode Draw von TRectangle aufgerufen. Nur bei virtuellen und dynamischen Methoden wird wohl zur Laufzeit eine Typüberprüfung vollzogen.

neolithos 19. Feb 2004 10:24

Re: Klassen in Delphi
 
Eine Klasse besteht soviel ich weis aus einer

Methoden-Tabelle (glaub VMT genannt) und den Daten auch als Instanze bezeichnet.

Beides ist getrennt.


wird nun TRectangle.Show aufgerufen geschieht das so

Delphi-Quellcode:
TRectangle.Show(Figure, 'TFigure.Create / TRectangle(Figure).Draw');
Die Instanze wird als erster Hidden-Parameter übergeben.

EDIT: Hättest du in Show auf einen Member von TRectangle zugegriffen wäre es erst zu einer AV gekommen. Member von TFigure wären ohne Probleme möglich gewesen.

Jens Schumann 19. Feb 2004 10:25

Re: Klassen in Delphi
 
Zitat:

Zitat von Chewie
D.h. im Compilat steht gar nix von TFigure.Draw, sondern es wird einfach die Methode Draw von TRectangle aufgerufen. Nur bei virtuellen und dynamischen Methoden wird wohl zur Laufzeit eine Typüberprüfung vollzogen.

Ahh - das klingt logisch.

tmode00 5. Jul 2005 17:02

Re: Klassen in Delphi
 
http://www.luckie-online.de/Tutorials/ >>tolle wurst, link tod!

Treffnix 5. Jul 2005 17:12

Re: Klassen in Delphi
 
Zitat:

Zitat von tmode00
http://www.luckie-online.de/Tutorials/ >>tolle wurst, link tod!

Ich vermisse mal wieder die Eigeninitiative. Ich hab mich gerade mal von luckie-online.de durchgeklickt und hatte nach weniger als 5 Sekunden das hier http://www.luckie-online.de/Developer/Delphi/Tutorials/

Luckie 5. Jul 2005 17:15

Re: Klassen in Delphi
 
Link korregiert. Aber das wäre auch etwas freundlicher gegangen. :roll:

negaH 5. Jul 2005 17:59

Re: Klassen in Delphi
 
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
...
    TRectangle(Figure).Show('TFigure.Create / TRectangle(Figure).Draw');
...
Ich habe das Tut nicht gelesen, gebe aber Sakura absolut Recht. Dieses Beispiel ist ein absolutes Negativbeispiel wie man es auf garkeinen Fall machen sollte. Es könnte aber als Eingangs-Beispiel für die Vermeidung von harten TypCast bei Klassen dienen. Denn so wie nachfolgend wäre der TypCast OOP konform richtiger gewesen:

Delphi-Quellcode:

 (Figure as TRectangle).Show;
Dieser Typcast würde dann eine Exception zu Laufzeit erzeugen, das TFigure NICHT von TRectangle abgeleitet wurde, und somit auf diesen offensichtlichen Programmierfehler hinweisen.

Gruß Hagen

Luckie 5. Jul 2005 19:05

Re: Klassen in Delphi
 
So, ihr habt mich überzeugt ;), in der neuen Version ist es verbessert. Link siehe erstes Posting.

GuenterS 5. Jul 2005 20:06

Re: Klassen in Delphi
 
Zitat:

Zitat von negaH
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
...
    TRectangle(Figure).Show('TFigure.Create / TRectangle(Figure).Draw');
...
Ich habe das Tut nicht gelesen, gebe aber Sakura absolut Recht. Dieses Beispiel ist ein absolutes Negativbeispiel wie man es auf garkeinen Fall machen sollte. Es könnte aber als Eingangs-Beispiel für die Vermeidung von harten TypCast bei Klassen dienen. Denn so wie nachfolgend wäre der TypCast OOP konform richtiger gewesen:

Delphi-Quellcode:

 (Figure as TRectangle).Show;
Dieser Typcast würde dann eine Exception zu Laufzeit erzeugen, das TFigure NICHT von TRectangle abgeleitet wurde, und somit auf diesen offensichtlichen Programmierfehler hinweisen.

Gruß Hagen

Übrigens TFigure ist auch nicht von TRectangle abgeleitet, sondern umgekehrt :grins:

Und die Exception gibts in dem Fall hoffentlich nur wenn es sich um statische Bindung handelt, bei dynamischer bzw. virtueller Bindung erwart ich mir, dass ich da keine bekomme...

Und wie wärs mit...
Delphi-Quellcode:
if (Figure is TRectangle) then
   TRectangle(Figure).Show;
Da würdest schon zur Compiletime merken, wenn TRectangle nicht von TFigure abgeleitet ist.

negaH 5. Jul 2005 23:00

Re: Klassen in Delphi
 
Zitat:

Da würdest schon zur Compiletime merken, wenn TRectangle nicht von TFigure abgeleitet ist.
Nein würdest du nicht merken :) Denn das Ziel war es die Methode .Show; aufzurufen von einer Klasse die garkeine solche Methode implementiert. Und das sollte UNMÖGLICH sein, tja wenn da nicht der harte TypCast wäre der die Typsicherheit des Compilers ausschaltet. Das Ziel war es eben NICHT dynamisch zur Laufzeit auf nicht vorhersagebare Umweltbedingungen, sprich dynamisch allozierte Klassenobjekte zu reagieren. In dem besagtem Beispiel war schon im Source die zu verwendende Klasse fixiert, ergo ist der "as" Operator das probatest Mittel um "falsche" Typcast durch "schusselige" Programmierungen zu verhindern.

Der "is" Operator im Zusammenhang mit der IF THEN Abfrage ist keine Typüberprüfung die zur Compiletime durch den Compiler durchgeführt wird. Die "is" und "as" Operatoren sind ausschließlich Laufzeitüberprüfungen.

Gruß Hagen

GuenterS 6. Jul 2005 07:46

Re: Klassen in Delphi
 
Zitat:

Zitat von negaH
Der "is" Operator im Zusammenhang mit der IF THEN Abfrage ist keine Typüberprüfung die zur Compiletime durch den Compiler durchgeführt wird. Die "is" und "as" Operatoren sind ausschließlich Laufzeitüberprüfungen.


:grübel:

Laut Hilfe in Delphi...
Zitat:

Zitat von Delphi Hilfe
Der Operator is führt eine dynamische Typprüfung durch. Mit ihm können Sie den aktuellen Laufzeittyp eines Objekts ermitteln. Der Ausdruck

Objekt is Klasse

gibt True zurück, wenn Objekt eine Instanz der angegebenen Klasse oder eines ihrer Nachkommen ist. Trifft dies nicht zu, wird False zurückgegeben (hat Objekt den Wert nil, ist der Rückgabewert ebenfalls False). Wenn der deklarierte Typ von Objekt nicht in Beziehung zu Klasse steht (wenn die Typen also unterschiedlich und nicht voneinander abgeleitet sind), gibt der Compiler eine Fehlermeldung aus. Ein Beispiel:

if ActiveControl is TEdit then TEdit(ActiveControl).SelectAll;

Diese Anweisung prüft zuerst, ob die Variable eine Instanz von TEdit oder einem ihrer Nachkommen ist, und führt anschließend eine Typumwandlung in TEdit durch.

Dann scheint die Fehlerhaft zu sein, denn wenn der Compiler es merkt, dann ist das zur Compilezeit, zur Laufzeit selber hat der Compiler nichts mehr am Programm zu tun.

negaH 6. Jul 2005 22:53

Re: Klassen in Delphi
 
Zitat:

dynamische Typprüfung durch. Mit ihm können Sie den aktuellen Laufzeittyp eines Objekts ermitteln.
was sagt die Delphi Hilfe ?

dynamische Typprüfung, also keine statische zur Compiletime.
aktuellen Laufzeittyp eines Objekts, da steht es doch Laufzeit

Wenn es so wäre wie du es meinst so müsste:
1.) die if then Abfrage ja sinnloser Code sein
2.) der Compiler beim kompilieren des Programmes schon einen Fehler bringen, tut er das ?

Gruß Hagen

GuenterS 7. Jul 2005 07:48

Re: Klassen in Delphi
 
Zitat:

Der Ausdruck

Objekt is Klasse

gibt True zurück, wenn Objekt eine Instanz der angegebenen Klasse oder eines ihrer Nachkommen ist. Trifft dies nicht zu, wird False zurückgegeben (hat Objekt den Wert nil, ist der Rückgabewert ebenfalls False). Wenn der deklarierte Typ von Objekt nicht in Beziehung zu Klasse steht (wenn die Typen also unterschiedlich und nicht voneinander abgeleitet sind), gibt der Compiler eine Fehlermeldung aus.
Um mal die (unrevelanten) Aussagen der Delphi- Hilfe wegzulassen...

Da steht geschrieben, dass der Compiler dies tut, da denke ich schon irgendwie, dass es eben nicht (nur) zur Laufzeit passiert.

Der "If then" Konstrukt macht schon Sinn, er prüft ja nicht nur zur CompileZeit (ganz grobe Fälle ab) sondern auch zur Laufzeit.

Luckie 29. Okt 2005 07:32

Re: Klassen in Delphi
 
Es gibt eine neue Version des PDF dieses Tutorials. Dank OpenOffice 2.0 jetzt mit Lesezeichen für die Kapitel. Alles weiter im ersten Posting: http://www.delphipraxis.net/internal...ct.php?t=18769

jbg 29. Okt 2005 09:49

Re: Klassen in Delphi
 
[quote="GuenterS"]
Zitat:

er prüft ja nicht nur zur CompileZeit (ganz grobe Fälle ab) sondern auch zur Laufzeit.
Und diese "ganz groben Fälle" sind wenn du eine Instanz mit einer der Klasse aus einer ganz anderen Vererbungshierarchie prüfst.

Delphi-Quellcode:
if Firgure is TStringList then // hier meckert der Compiler weil TStringList nicht in der gesamten Vererbungshierarchie von TFigure vorkommt.

jbg 29. Okt 2005 10:06

Re: Klassen in Delphi
 
Wenns auch nur ein marginaler Fehler ist, aber diese Warnung hast du wohl abgetippt und dabei das "O" von TObject kleingeschrieben:
Zitat:

[Warnung] Unit1.pas(20): Methode 'Destroy' verbirgt virtuelle Methode vom Basistyp 'Tobject'
Die Groß- und Kleinschreibung von Bezeichnern ändert sich in den Code-Beispielen.
Zitat:

(MyFruit as TcitrusFruit).Squeeze
Zitat:

Dynamische Methoden sollten nur verwendet werden, wenn sich dadurch ein nachweisbarer Nutzen
ergibt. allgemein sollte man virtuelle Methoden verwenden.
Die VCL nutzt dynamic Methoden (zusätzlich) immer dann, wenn sie von einer Benutzer-Interaktion aufgerufen werden wie z.B. KeyDown, KeyUp, KeyPress, Click, DblClick, MouseDown, MouseUp, MouseMove, ...

Luckie 29. Okt 2005 14:07

Re: Klassen in Delphi
 
Danke für die Hinweise. Wenn es ein Update gibt, werde ich das (hoffentlich) berücksichtigen. Jetzt lasse ich es erstmal so.

Luckie 6. Mai 2006 01:52

Re: Klassen in Delphi
 
Das PDF wurde neu erzeugt. Die Seitenzahlen im Inhaltsverzeichnis sind jetzt Links und die Kapitel im Adobe Acrobate Reader werden als Bookmarks angezeigt.

Downmloadlink im ersten Beitrag.

dino 24. Jul 2006 10:14

Re: Klassen in Delphi
 
schon in 1_1 hab ich mein erstes Problem:

Delphi-Quellcode:
procedure TForm1.btnFahrenheitClick(Sender: TObject);
var
  Temp: TTemperatur;
begin
  Temp := TTemperatur.create(StrToFloat(edtTemp.Text));
  try
    stcErgebniss.Caption := FloatToStrF(Temp.Fahrenheit, ffNumber, 8, 2);
  finally
    FreeAndNil(Temp);
  end;
end;
TTemperature wird nur hier aufgerufen, aber nirgends deklariert...
nun wird aber Temp.Fahrenheit aufgerufen, nur wie ist das möglich?

ist TTemperatur womöglich doch irgendwo definiert, und ich seh es nicht?

cruiser 24. Jul 2006 10:35

Re: Klassen in Delphi
 
Zeile 45 und 46:

Delphi-Quellcode:
uses
  TTemp;
die TTemp.pas liegt im Demoverzeichnis ;)

dino 24. Jul 2006 11:10

Re: Klassen in Delphi
 
Liste der Anhänge anzeigen (Anzahl: 1)
danke jetzt seh ichs
übrigens hat der Fehlerteufel wieder zugeschlagen:

Luckie 20. Okt 2007 18:05

Re: Klassen in Delphi
 
Das Tutorial wurde - im Zuge der Vereinheitlichung des Layout meiner PDF-Dokumente - noch mal neu mit Latex geschrieben. Inhaltlich hat sich nichts geändert. Das Layout ist jetzt doppelseitig und kann so schön ausgedruckt und gebunden werden (falls das jemand machen sollte ;) ).

Link im ersten Posting.

mschaefer 21. Okt 2007 10:50

Re: Klassen in Delphi
 
Feines Tutorial, gut gemacht, gefällt mir ! Grüße // Martin

Luckie 21. Okt 2007 12:59

Re: Klassen in Delphi
 
Danke dir. :P

Dezipaitor 21. Okt 2007 14:16

Re: Klassen in Delphi
 
Sieht das Security Programming Tutorial dann auch so aus?

Luckie 21. Okt 2007 14:26

Re: Klassen in Delphi
 
Wenn es dann irgendwann mal fertig sein sollte, ja.

Dezipaitor 21. Okt 2007 14:34

Re: Klassen in Delphi
 
Zu großes Thema oder?

Luckie 21. Okt 2007 14:44

Re: Klassen in Delphi
 
Zu wenig Zeit. ;) Aber das gehört nicht hier her.


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:18 Uhr.
Seite 1 von 2  1 2      

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