Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Klassenmethoden in Delphi (https://www.delphipraxis.net/12846-klassenmethoden-delphi.html)

Phoenix 5. Dez 2003 07:45


Klassenmethoden in Delphi
 
Mannomann, manche Sprachkonzepte fallen mir immer noch schwer.

Wie definieren ich eine Klassenmethode, die eine Instanz der Klasse erzeugt, darauf arbeitet, eine Rückgabe erzeugt und das Objekt wieder freigibt?

Ich habe bisher:
Delphi-Quellcode:
MyClass = class(TObject)
   constructor Create; override;
   destructor Destroy; override;
   class procedure GetValues(var val1: string; var val2: string);
end;

class procedure MyClass.GetValues(var val1: string; var val2: string);
var
   obj: MyClass;
begin
   obj := MyClass.Create;
   val1 := obj.ClassName;
   val2 := 'irgendwas';
   obj.free;
end;
Wenn ich nun z.B. von der Hauptform aus mit
Delphi-Quellcode:
MyClass.GetValues(s1, s2);
darauf zugreifen will, bekomme ich immer einen EVariantError (Ungültige Varianten-Typumwandlung).

Kann mir jemand sagen, was ich da falsch gemacht habe?

EDIT: Natürlich sind contructor und destructor korrekt implementiert, wenn ich das was ich aus der Klassenmethode heraus machen will direkt auf dem Objekt mache tut da auch.
/EDIT

OLLI_T 5. Dez 2003 08:11

Re: Klassenmethoden in Delphi
 
Moin Phoenix!

Dein Beispiel kannst Du so niemals compiliert haben. Das override hinter dem Constructor muss weg => Dann läuft die Kiste einwandfrei. Den Bock hast Du sicher an anderer Stelle geschossen, die Du den Augen der Allgemeinheit vorenthalten hast. :cyclops:

Gruss

OLLI

choose 5. Dez 2003 08:53

Re: Klassenmethoden in Delphi
 
Hallo Phoenix,

vielleicht noch ein Tipp?
  • ClassName ist eine Klassenmethode, Du brauchst deshalb nicht erst ein Exemplar der Klasse zu erstellen
  • Innerhalb von Klassenmethoden kannst Du die Klasse mit Self referenzieren, also
    auch Klassenmethoden mit
    Delphi-Quellcode:
    Self.AClassMethod
    aufrufen
  • Den Konstruktor kann man auch als "Nachricht an die Klasse" verstehen, und kann deshalb innerhalb von Klassenmethoden auch so verwendet werden
    Delphi-Quellcode:
    myObject:= Self.Create
Deine Klassenmethode könnte deshalb vielleicht so aussehen:
Delphi-Quellcode:
class procedure TMyClass.GetValues(out AValue1, AValue2: string);
begin
  AValue1:= Self.ClassName;
  with Self.Create do
  try
    Result:= AMethodFromInstance;
  finally
    Free;
  end;
end;
Der Vorteil: Sollte die Methode AMethodFromInstance eine virtuelle Methode sein und der Aufruf der Klassenmethode GetValues nicht an TMyClass sondern an einen Erben gerichtet sein, bei dem die Methode AMethodFromInstance überschrieben worden ist, würde wg der Polymorphie diese Überladene Methode aufrufen werden, weil ein Exemplar der geerbten Klasse erzeugt worden wäre.
Wäre das Exemplar in GetValues hingegen mit einer Konkreten Klasse erzeugt worden, also zB TMyClass.Create, würde stattdessen immer die dort implementierte Version von AMethodFromInstance aufgerufen werden...

Phoenix 5. Dez 2003 08:54

Re: Klassenmethoden in Delphi
 
Nein, das Override muss da hin, schliesslich ist meine orginal-Klasse auch nicht von TObject abgeleitet...

Wie ich schon geschriben habe: Constructor und destructor funktionieren einwandfrei, die Methoden die ich in der Klassenmethode brauche auch! Da kann der Fehler also nicht liegen.

choose 5. Dez 2003 09:03

Re: Klassenmethoden in Delphi
 
Zitat:

Zitat von Phoenix
[...] schliesslich ist meine orginal-Klasse auch nicht von TObject abgeleitet [...]. Constructor und destructor funktionieren einwandfrei, die Methoden die ich in der Klassenmethode brauche auch! Da kann der Fehler also nicht liegen.

Hallo Phoenix,
mit TObject klappt das prima und die Exception EVariantError deutet auf einen Fehler in einem Abschnitt hin, den Du bisher nicht veröffentlich hast...

Phoenix 5. Dez 2003 09:15

Re: Klassenmethoden in Delphi
 
Delphi-Quellcode:
MyClass: TObject;
   public
      class procedure GetValues(var value1: string; var value2: string; const when: TDateTime = 0; const critaria: string = '');
end;

class procedure MyClass.GetValues(var value1: string; var value2: string; const when: TDateTime = 0; const critaria: string = '');
begin
  // do nothing
end;
Aufruf:
Delphi-Quellcode:
uses
   UnitMyClass, SysUtils;

var
   val1, val2, crit: string;
begin
   crit := 'Test';
   MyClass.GetValues(val1, val2, now, test); // hier gibts den fehler
end;
So schaut das bei mir aus (mit dem unterschied, das ich bei do nothing einen etwas grösseren auskommentierten block habe, und die werte ein wenig anders heissen.

Also auch wenn die Methode leer ist, gibt es den EVariantError bereits beim aufruf.

choose 5. Dez 2003 09:20

Re: Klassenmethoden in Delphi
 
Ist Test vielleicht vom Typ Variant?

choose 5. Dez 2003 09:33

Re: Klassenmethoden in Delphi
 
Diese Lösung scheint zu funktionieren
Delphi-Quellcode:
type
  TMyClass = class(TObject)
  public
    class procedure GetValues(out AValue1, AValue2: string;
      const AWhen: TDateTime=0; const ACritaria: string='');
  end;

class procedure TMyClass.GetValues(out AValue1, AValue2: string;
  const AWhen: TDateTime; const ACritaria: string);
begin
  AValue1:= '42';
  AValue2:= 'I always knew there´s something wrong in the universe...';
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  myString1: string;
  myString2: string;
  myCriteria: string;
begin
  myCriteria:= 'What do you get if you multiply six by nine?';
  TMyClass.GetValues(myString1, myString2, Now, myCriteria);
  Showmessage(myString1+#10#13+myString2);
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 16: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