Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Klasseneigenschaften und ihre Getter (abstrakte Klasse) (https://www.delphipraxis.net/92016-klasseneigenschaften-und-ihre-getter-abstrakte-klasse.html)

CalganX 13. Mai 2007 13:26


Klasseneigenschaften und ihre Getter (abstrakte Klasse)
 
Hi,
ich habe eine Basisklasse TCXXmlConnection, die nur als Basis existieren soll. Sie ist also praktisch komplett abstrakt:
Delphi-Quellcode:
  TCXXmlConnection = class
  private
    fDataURL: string;

  public
    function Prepare: boolean; virtual; abstract;
    function Ready: boolean; virtual; abstract;
    function Close: boolean; virtual; abstract;

    class function RequiredLibInstalled: boolean; virtual; abstract;

    function GetProject(const AProjectID: string): TCXProjectInfo; virtual; abstract;
    function GetVersionsForProject(const AProjectID: string;
      AGetDownloads: boolean = true): TCXVersionArray; virtual; abstract;
    function GetDownloadsForVersion(const AProjectID: string;
      const AVersionID: string): TCXDownloadArray; virtual; abstract;

  published
    property DataURL: string read fDataURL write fDataURL;
  end;
Soweit alles kein Problem. Nun möchte ich aber eine Klasseneigenschaft mit einem Getter hinzufügen. Der Getter wiederum soll virtuell-abstrakt sein.
Delphi-Quellcode:
  TCXXmlConnection = class
  private
    fDataURL: string;

  strict protected
    class function GetLibName: string; virtual; abstract;

  public
    function Prepare: boolean; virtual; abstract;
    function Ready: boolean; virtual; abstract;
    function Close: boolean; virtual; abstract;

    class function RequiredLibInstalled: boolean; virtual; abstract;

    function GetProject(const AProjectID: string): TCXProjectInfo; virtual; abstract;
    function GetVersionsForProject(const AProjectID: string;
      AGetDownloads: boolean = true): TCXVersionArray; virtual; abstract;
    function GetDownloadsForVersion(const AProjectID: string;
      const AVersionID: string): TCXDownloadArray; virtual; abstract;

  published
    property DataURL: string read fDataURL write fDataURL;
    class property LibName: string read GetLibName;
  end;
So bekomme ich erstmal den Fehler, dass GetLibName statisch sein muss. Füge ich aber static; hinzu, bekomme ich den seltsamen Fehler (Bug?)
Zitat:

[Pascal Fehler] CXXmlConnection.pas(14): E2169 Felddefinition nicht erlaubt nach Methoden oder Eigenschaften
David bekommt unter D2005 einen Fehler, der da etwas eindeutiger ist:
Zitat:

STATIC kann nur für nicht-virtuelle Klassenmethoden verwendet werden
Gibt es keine Möglichkeit den Getter einer Klasseneigenschaft virtuell-abstrakt zu machen?

Chris

Christian Seehase 13. Mai 2007 14:55

Re: Klasseneigenschaften und ihre Getter (abstrakte Klasse)
 
Moin Chris,

Zitat:

Zitat von OH - D2006
Class property accessors must themselves be declared as class static methods, or class fields.

ausserdem:

Zitat:

Zitat von OH - D2006
Class properties cannot be published,...


CalganX 13. Mai 2007 15:01

Re: Klasseneigenschaften und ihre Getter (abstrakte Klasse)
 
Hi Christian,
mit anderen Worten heißt das aber auch, dass es nicht möglich ist, einen solchen Getter virtuell-abstrakt zu machen, richtig? Denn schließlich spuckt er mir einen Fehler aus, wenn ich static zusammen mit virtual; abstract; verwende.

Chris

Christian Seehase 13. Mai 2007 15:05

Re: Klasseneigenschaften und ihre Getter (abstrakte Klasse)
 
Moin Chris,

Du könntest aber die Eigenschaft ohne class deklarieren, und dann die Getter-Methode als virtual und abstract.
Ich weiss allerdings nicht, ob dass dann den von Dir gewünschten Effekt hat.

static und virtual schliessen sich eh' gegenseitig aus.

Apollonius 13. Mai 2007 16:00

Re: Klasseneigenschaften und ihre Getter (abstrakte Klasse)
 
Könnte man das nicht umgehen, indem man eine statische Dummymethode verwendet, die nur die tatsächliche abstrakte Methode aufruft?

alzaimar 13. Mai 2007 16:39

Re: Klasseneigenschaften und ihre Getter (abstrakte Klasse)
 
Ich habe es so gelöst:
Delphi-Quellcode:
Type
  TMyClass = class
  Private
     Function GetMyProperty : String;
     Function DoGetMyProperty; String; Virtual; Abstract; // <--- Das hier wird überschrieben
  Public
     [/edit] Class {/edit] Property MyProperty : String Read GetMyProperty;
  End;


Function TMyClass.GetMyProperty : String;
Begin
  Result := DoGetMyProperty;
End;

CalganX 13. Mai 2007 16:41

Re: Klasseneigenschaften und ihre Getter (abstrakte Klasse)
 
Hi,
das ist zwar jetzt keine Klasseneigenschaft, aber ich schätze sowas in der Art wird auch mit Klasseneigenschaften möglich sein.

Danke, werde ich gleich mal ausprobieren.

Chris

alzaimar 14. Mai 2007 08:12

Re: Klasseneigenschaften und ihre Getter (abstrakte Klasse)
 
Zitat:

Zitat von CalganX
Hi,
das ist zwar jetzt keine Klasseneigenschaft,...

:mrgreen:

negaH 14. Mai 2007 09:20

Re: Klasseneigenschaften und ihre Getter (abstrakte Klasse)
 
Überlege mal logisch

1.) was soll eine abstrakte Methode für einen Sinn machen wenn man sie nicht als virtual deklarieren kann ? Ergo: abstrakte Methoden sind fast immer virtual und das muß gehen.

2.) eine Klassenmethode greift auf die Klasse zu, dh. es gibt keine individuelle Instance zu Laufzeit. Das bedeutet das es keine individuellen Felder = Daten zu einer Klasse geben kann und das führt uns zu dem fakt das Properties für eine Klasse keinen Sinn machen.

Properties sind systembedingt eine Schnittstelle die immer auf einer Instance einer Klasse zugreifen und niemals direkt nur auf die Klasse ansich.

Lösung könnte so aussehen

Delphi-Quellcode:
type
  TXYZ = class
  private
    function GetClassNameProp: String;
  public
    class function GetClassName: String; virtual; abstract;
  published
    property ClassName: String read GetClassNameProp;
  end;

function TXYZ.GetClassNameProp: String;
begin
  Result := GetClassName;
end;
Wie gesagt, um auf die Property .ClassName zugreifen zu können musst du vorher eine Instance, also ein Objekt, vom Typ TXYZ allozoiert haben. Erst danach kannst du auf .ClassName zugreifen. In diesem Moment benötigt man keine Klassenmethoden mehr.
Mit der Klassenmethode .GetClassName kannst du aber OHNE Allokation einer Objectinstance auf die Klasse ansich zugreifen, also so -> TXYZ.GetClassName.

Beide Problem die du hast sind also absolut logisch herleitbar und du möchtest eben ein Feature das keinen Sinn macht im Konzept der VCL-OOP.

Gruß Hagen

CalganX 14. Mai 2007 16:25

Re: Klasseneigenschaften und ihre Getter (abstrakte Klasse)
 
Hi,
der erste Punkt ist mir klar. Den will ich auch gar nicht in Frage stellen. Aber warum sollen Klasseneigenschaften überflüssig sein? Klasseneigenschaften selbst sind schonmal Bestandteil der VCL-OOP, wie man daran erkennt, dass sowas funktioniert:
Delphi-Quellcode:
TABC = class
private
  class function GetMyProp: string; static;
public
  class proprety MyProp: string read GetMyProp;
end;
(zumindest so in der Art, hab gerade kein Delphi zur Hand, um die genaue Syntax zu überprüfen.)

Die Idee ist, eben ohne Instanz Informationen über die Klasse zu erhalten. In meinem Fall zum Beispiel der Name der verwendeten Bibliothek (für jede Bibliothek gibt es eine Klasse, die Nachfahre einer abstrakten Klasse ist, die bereits die entsprechenden Methoden besitzen soll). Nun macht es keinen Sinn für die abstrakte Basisklasse irgendwelche Methoden zu implementieren, weil die Basisklasse selber nie verwendet werden wird. Alles Wesentliche, wie z.B. der Getter, soll auf die Nachfahren übertragen werden.
Sinn ist dann, dass sowas funktioniert:
Delphi-Quellcode:
var
  BaseConnection: TBaseConnection;
begin
  ShowMessage('Verwende ' + TOmniXmlConnection.LibName + ' als Bibliothek.');
  BaseConnection := TOmniXmlConnection.Create;
end;
Besonders interessant wird es dann, wenn die Klasse zur Designtime der Klassen noch gar nicht bekannt ist, sondern das ganze über einen Parameter vom Typ class of TBaseConnection läuft. Natürlich wäre das eine funktionierende Alternative:
Delphi-Quellcode:
TABC2 = class
public
  class function GetMyProp: string; virtual; abstract;
end;
Das funktioniert auch und ist gar kein Problem zu implementieren, aber es war halt mein Grundgedanke, das mit Eigenschaften zu lösen. So, dass der Getter dann vom Nachfahren nur noch überschrieben werden muss.

Die Unsinnigkeit meiner Idee kann ich also noch nicht so ganz nachvollziehen und ich denke meine Idee dahinter ist vielleicht jetzt etwas deutlicher geworden.

Die Lösung von alzaimar ist natürlich schon in etwa das, was ich eigentlich vor hatte. Nur wäre es meiner Meinung nach auch nicht widersprüchlich, wenn man den Umweg über die Klassenmethode nicht gehen müsste.

Chris


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