[Erledigt] Verständnisfrage zu Klassen
-
- Lazarusforum e. V.
- Beiträge: 999
- Registriert: Do 17. Apr 2008, 01:59
- OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
- CPU-Target: Intel i7-10750 64Bit
- Wohnort: Freiburg
[Erledigt] Verständnisfrage zu Klassen
Ist das Init für Klassen 'Pflicht' oder 'Guter Stil', oder genügt es wenn man die Propertis mit Defaults bestückt, wo notwendig?
Was, außer der Startzuweisung sollte in der Init erfolgen?
(Endlich fange ich mal mit Klassen an )
Was, außer der Startzuweisung sollte in der Init erfolgen?
(Endlich fange ich mal mit Klassen an )
Zuletzt geändert von MacWomble am Fr 11. Jan 2019, 12:51, insgesamt 1-mal geändert.
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
- m.fuchs
- Lazarusforum e. V.
- Beiträge: 2640
- Registriert: Fr 22. Sep 2006, 19:32
- OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
- CPU-Target: x86, x64, arm
- Wohnort: Berlin
- Kontaktdaten:
Re: Verständnisfrage zu Klassen
Init? Du meinst den Konstruktor? Der wird im Allgemeinen als Create benannt.
Wenn du keine Initialisierung vornehmen musst, dann kannst du ihn dir sparen. Das ist völlig legitim und auch kein schlechter Stil.
Reinpacken tust du halt alles, was zum erstmaligen Nutzen eines Objektes nötig ist: Default-Daten in die einzelnen Felder packen, Unterobjekte erstellen, sonstewas.
Wenn du ein konkretes Beispiel hast, kann man es sicher auch besser erklären.
Wenn du keine Initialisierung vornehmen musst, dann kannst du ihn dir sparen. Das ist völlig legitim und auch kein schlechter Stil.
Reinpacken tust du halt alles, was zum erstmaligen Nutzen eines Objektes nötig ist: Default-Daten in die einzelnen Felder packen, Unterobjekte erstellen, sonstewas.
Wenn du ein konkretes Beispiel hast, kann man es sicher auch besser erklären.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
-
- Lazarusforum e. V.
- Beiträge: 999
- Registriert: Do 17. Apr 2008, 01:59
- OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
- CPU-Target: Intel i7-10750 64Bit
- Wohnort: Freiburg
Re: Verständnisfrage zu Klassen
Danke für die Info, das hilft weiter.
Ich meinte Init, weil ich das in einem Delphi.Beispiel gesehen habe. Create ist klar.
Dann bastel ich jetzt mal weiter - fängt so langsam an, Spass zu machen ...
Ich meinte Init, weil ich das in einem Delphi.Beispiel gesehen habe. Create ist klar.
Dann bastel ich jetzt mal weiter - fängt so langsam an, Spass zu machen ...
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
- m.fuchs
- Lazarusforum e. V.
- Beiträge: 2640
- Registriert: Fr 22. Sep 2006, 19:32
- OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
- CPU-Target: x86, x64, arm
- Wohnort: Berlin
- Kontaktdaten:
Re: [Erledigt] Verständnisfrage zu Klassen
Kleiner Tipp: Wenn du einen Konstruktor schreibst, setze in die erste Zeile
Damit wird der Kontruktor der Elternklasse aufgerufen. Das ist zwar beim Standardfall (der Ableitung von TObject) nicht notwendig, aber man kann dann später leichter die Elternklassen ändern.
Code: Alles auswählen
inherited Create;
Damit wird der Kontruktor der Elternklasse aufgerufen. Das ist zwar beim Standardfall (der Ableitung von TObject) nicht notwendig, aber man kann dann später leichter die Elternklassen ändern.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
Re: [Erledigt] Verständnisfrage zu Klassen
MacWomble hat geschrieben:Ist das Init für Klassen 'Pflicht' oder 'Guter Stil', oder genügt es wenn man die Propertis mit Defaults bestückt, wo notwendig?
Was, außer der Startzuweisung sollte in der Init erfolgen?
(Endlich fange ich mal mit Klassen an )
Meinst du "object" oder "class"?
m.fuchs hat geschrieben:Init? Du meinst den Konstruktor? Der wird im Allgemeinen als Create benannt.
Wenn du keine Initialisierung vornehmen musst, dann kannst du ihn dir sparen. Das ist völlig legitim und auch kein schlechter Stil.
Das geht schief, wenn "class" gemeint ist. Klassen (also z.B. type TMyClass = class) werden auf dem Heap angelegt, und die Speicherreservierung erfolgt im Konstructor. Kein Aufruf von Create -> keine Speicher -> crash.
Code: Alles auswählen
type
TMyObject = class
A: Integer;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
obj: TMyObject;
begin
obj.A := 1; // <--- crash here!
end;
Die älteren Objekte (also: TMyObject = object) dagegen liegen auf dem Stack und kommen ohne Konstruktor aus, sofern keine virtuellen Methoden deklariert sind, denn der Aufbau der VMT (virtuelle-Methoden-tabelle) erfolgt wieder im Konstructor.
- m.fuchs
- Lazarusforum e. V.
- Beiträge: 2640
- Registriert: Fr 22. Sep 2006, 19:32
- OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
- CPU-Target: x86, x64, arm
- Wohnort: Berlin
- Kontaktdaten:
Re: [Erledigt] Verständnisfrage zu Klassen
wp_xyz hat geschrieben:m.fuchs hat geschrieben:Init? Du meinst den Konstruktor? Der wird im Allgemeinen als Create benannt.
Wenn du keine Initialisierung vornehmen musst, dann kannst du ihn dir sparen. Das ist völlig legitim und auch kein schlechter Stil.
Das geht schief, wenn "class" gemeint ist. Klassen (also z.B. type TMyClass = class) werden auf dem Heap angelegt, und die Speicherreservierung erfolgt im Konstructor. Kein Aufruf von Create -> keine Speicher -> crash.
Es ging aber nicht um den Aufruf von Create, sondern ob in einer abgeleiteten Klasse eine implementiert werden muss. Und das muss eben nicht sein.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
-
- Lazarusforum e. V.
- Beiträge: 999
- Registriert: Do 17. Apr 2008, 01:59
- OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
- CPU-Target: Intel i7-10750 64Bit
- Wohnort: Freiburg
Re: [Erledigt] Verständnisfrage zu Klassen
Bevor ihr euch die Köpfe abreisst:
Ich habe mir im Moment folgende die angehängte Unit erstellt. Ich habe Create auch angelegt, aber es ging um das tatsächlich um das Init.
Aber ich habe dennoch eine Frage dazu:
Wenn ich es richtig verstanden habe, sollten Methoden, welche auf die DB zugreifen (um das Objekt zu füllen bzw zu speichern etc.), in eine eigene Unit. Habe ich das richtig verstanden?
Ich habe mir im Moment folgende die angehängte Unit erstellt. Ich habe Create auch angelegt, aber es ging um das tatsächlich um das Init.
Aber ich habe dennoch eine Frage dazu:
Wenn ich es richtig verstanden habe, sollten Methoden, welche auf die DB zugreifen (um das Objekt zu füllen bzw zu speichern etc.), in eine eigene Unit. Habe ich das richtig verstanden?
- Dateianhänge
-
- uhistorie.pas
- (5.83 KiB) 83-mal heruntergeladen
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
Re: [Erledigt] Verständnisfrage zu Klassen
m.fuchs hat geschrieben:Es ging aber nicht um den Aufruf von Create, sondern ob in einer abgeleiteten Klasse eine implementiert werden muss.
So explizit steht das nirgendwo. Die Formulierungen hier im Forum sind meistens so, dass sie mindestens zwei Interpretationen zulassen.
-
- Beiträge: 351
- Registriert: Mi 25. Nov 2015, 17:06
- OS, Lazarus, FPC: Win 10 Pro | Lazarus 1.8.2 | FPC 3.0.4
- CPU-Target: i386 + x86_64
- Wohnort: in der Nähe von Stuttgart
- Kontaktdaten:
Re: [Erledigt] Verständnisfrage zu Klassen
@MacWomble Tipp: die ganzen Get und Set Funktionen kannst du dir auch sparen wenn sie nichts anderes machen außer lesen und schreiben.
Folgendes funktioniert auch wunderbar:
Nur wenn du durch das Ändern einer property auch andere Dinge ändern musst benötigst du ein Set Funktion. Eine Get Funktion benötigt man eher selten, kommt aber vor. Ebenso kannst du den "write" Aspekt weglassen und dadurch eine nur lesbare Eigenschaft erzeugen, falls du das mal benötigst.
Als Beispiel nehme ich mal einen Auszug aus meinem aktuellen Projekt, bei dem ich u.a. einen Server schreibe. Der zugehörige Client überträgt beim Verbinden seine Version und der Server kann schauen ob diese Version überhaupt unterstützt wird oder ob sie gar zu alt ist und den Client darauf rausschmeißen:
Folgendes funktioniert auch wunderbar:
Code: Alles auswählen
TMyClass = class
private
FId: Integer;
public
property Id: Integer read FId write FId;
Nur wenn du durch das Ändern einer property auch andere Dinge ändern musst benötigst du ein Set Funktion. Eine Get Funktion benötigt man eher selten, kommt aber vor. Ebenso kannst du den "write" Aspekt weglassen und dadurch eine nur lesbare Eigenschaft erzeugen, falls du das mal benötigst.
Als Beispiel nehme ich mal einen Auszug aus meinem aktuellen Projekt, bei dem ich u.a. einen Server schreibe. Der zugehörige Client überträgt beim Verbinden seine Version und der Server kann schauen ob diese Version überhaupt unterstützt wird oder ob sie gar zu alt ist und den Client darauf rausschmeißen:
Code: Alles auswählen
type
TQuery = class
private
FVersion: AnsiString;
...
protected
function IsVersionSupported: Boolean; virtual; // In dieser Methode wird evaluiert ob FVersion noch unterstützt wird
...
public
property Version: AnsiString read FVersion write FVersion; // Die Version wird direkt in die Variable FVersion geschrieben bzw daraus gelesen
property VersionSupported: Boolean read IsVersionSupported; // Das ist eine Read-Only Eigenschaft die mir sagt ob die Version des Clients unterstützt wird
...
Code: Alles auswählen
InitiateSystemShutdownExA(nil, nil, 0, true, false, $0005000F);
-
- Lazarusforum e. V.
- Beiträge: 999
- Registriert: Do 17. Apr 2008, 01:59
- OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
- CPU-Target: Intel i7-10750 64Bit
- Wohnort: Freiburg
Re: [Erledigt] Verständnisfrage zu Klassen
Ok, vielen Dank. Das habe ich nun auch verstanden. Macht mir die Sache wesentlich einfacher und übersichtlicher !
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.