![]() |
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:
Soweit alles kein Problem. Nun möchte ich aber eine Klasseneigenschaft mit einem Getter hinzufügen. Der Getter wiederum soll virtuell-abstrakt sein.
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;
Delphi-Quellcode:
So bekomme ich erstmal den Fehler, dass GetLibName statisch sein muss. Füge ich aber static; hinzu, bekomme ich den seltsamen Fehler (Bug?)
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; Zitat:
Zitat:
Chris |
Re: Klasseneigenschaften und ihre Getter (abstrakte Klasse)
Moin Chris,
Zitat:
Zitat:
|
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 |
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. |
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?
|
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; |
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 |
Re: Klasseneigenschaften und ihre Getter (abstrakte Klasse)
Zitat:
|
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:
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.
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; 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 |
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:
(zumindest so in der Art, hab gerade kein Delphi zur Hand, um die genaue Syntax zu überprüfen.)
TABC = class
private class function GetMyProp: string; static; public class proprety MyProp: string read GetMyProp; end; 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:
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:
var
BaseConnection: TBaseConnection; begin ShowMessage('Verwende ' + TOmniXmlConnection.LibName + ' als Bibliothek.'); BaseConnection := TOmniXmlConnection.Create; end;
Delphi-Quellcode:
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.
TABC2 = class
public class function GetMyProp: string; virtual; abstract; end; 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 23:08 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