![]() |
Per Klasse auf übergeordnete Klasse zugreifen?
Moin,
ich möchte eine Komponente schreiben und einzelne Properties Kategorisch ordnen, so dass es im Objekt-Inspektor beispielsweise so aussieht: +Kategorie1 `- Property1 `- Property2 `- Property3 +Kategorie2 `- Property1 `- Property2 `- Property3 usw... Um dies zu lösen muss ich ja für jede Kategorie eine Klasse schreiben, die die dazugehörigen Properties beinhaltet. Das Problem ist jetzt, dass eines dieser Felder einer Kategorie auf ein Feld der Hauptklasse zugreifen muss, bloss kennt eine untergeordnete Klasse ja nicht seine übergeordnete. Ich könnte ja meine Hauptklasse vorwärsdeklarieren und ein Feld selbiger in meiner Kategorieklasse anlegen, wo die Hauptklasse im Constructor(?) der Unterklasse mittgeteilt wird... Die Frage ist eigentlich, ob dies der richtige weg ist? |
Re: Per Klasse auf übergeordnete Klasse zugreifen?
Hallo :hi:
ne andere Möglichkeit wären Events: OnPropertyChange oder sowas... mfg Christian |
Re: Per Klasse auf übergeordnete Klasse zugreifen?
Zitat:
Du kannst forward decl. benutzen. Du kannst auch all die anderen Tricks benutzen, um zu verhindern, dass deine Units irgendwann, aufgrund verschränkter Typen, 1.000 Zeilen haben (Gibt sogar Leute, die damit angeben so große Monster zu haben :lol: ) Du kannst hier mit Interfaces arbeiten, oder deiner Hauptklassse einen Vorgänger verpassen, der nur das enthält was du hier brauchst. Zitat:
|
Re: Per Klasse auf übergeordnete Klasse zugreifen?
Moin christian,
vielleicht habe ich es schlecht ausgedrückt, aber ich meinte es so: Ich habe eine Subklasse und eine Hauptklasse, die so aussehen:
Delphi-Quellcode:
So... TServer ist eine Klasse für die "Kategorie" "Server" die man nachher im OI sehen kann mit seinen Membern "Host" und "Port"...
TServer = class(TPersistent)
private function GetHost: string; procedure SetHost(const Host: string); function GetPort: Word; procedure SetPort(const Port: Word); published property Host: string read GetHost write SetHost; property Port: Word read GetPort write SetPort; end; TMainClass = class(TComponent) private FClientSocket: TClientSocket; FServer: TServer; published Server: TServer read FServer write FServer; end; Die privaten Methoden dieser Klasse müssen irgendwie an die gleichnamigen Properties des Feldes "FClientSocket" der Hauptklasse kommen... nur wie? Ich finde meine obige Idee "unsauber". Edit: @Elvis: wie komme ich an den Owner? TPersistent muss man keinen übergeben....welche Klasse sollte ich stattdessen verwenden? |
Re: Per Klasse auf übergeordnete Klasse zugreifen?
Zitat:
Du musst doch irgendwo in deiner MainClass dein TServer initialisieren, und das machst Du doch sicherlich etwa so im Constructor deiner MainClass:
Delphi-Quellcode:
Wenn Du jetzt aber den constructor deiner TServer Klasse überlädst, und so definierst:
constructor TMainClass.Create (AOwner : TComponent) ; override ;
begin FServer := TServer.Create ; end ;
Delphi-Quellcode:
kannst du in der MainClass so ein Objet erzeugen:
public
constructor Create (AMainClass : TMainClass) ; overload ;
Delphi-Quellcode:
Diesen Parameter kannst Du nun auswerten und z.B. in einer private property speichern.
constructor TMainClass.Create (AOwner : TComponent) ; override ;
begin FServer := TServer.Create (Self) ; end ; |
Re: Per Klasse auf übergeordnete Klasse zugreifen?
Delphi-Quellcode:
IMainDingens = interface
function getPort : Word; function getHost : String; procedure setPort (const value : Word); procedure setHost (const value : String); end;
Delphi-Quellcode:
TServer = class(TPersistent)
private fMainDingens : IMainDingens; ... public constructor Create(const owner : IMainDingens) end; Die Implementierung des Interfaces in deiner Komponente solte straight forward sein. ;) Du kannst die Getter/Setter dort auch als protected deklarieren, wodurch sie nicht ohne weiteres öffentlich veränderbar sind. ;) @Jelly Ich dachte seine Aggregate sind Komponenten, TPersistent hat keinen Owner, deshalb kann man ihn hier gleich auf das Interface typisieren und sich so type casts sparen. ;) |
Re: Per Klasse auf übergeordnete Klasse zugreifen?
Moin :)
Besten Dank für eure Hilfe. ;) @Elvis: WIeso ist es ein Interface und keine Klasse? (Nie mit solchen gearbeitet) |
Re: Per Klasse auf übergeordnete Klasse zugreifen?
Zitat:
Mit der Abstraktion über ein Interface kannst du die Verbindung zwischen den 2 Klassen in eine 3. Unit auslagern wodurch dein TServer keine Ahnung von der Hauptklasse haben muss. ;) So hast du 3 Units, die jeweils auf einen Moni passen im Gegensatz zu ... :kotz:
Delphi-Quellcode:
type
IMainDingens = interface function getPort : Integer; function getHost : string; procedure setPort(value : Integer); procedure setHost(value : string); property Port : Integer read getPort write setPort; property Host : string read getHost write setHost; end;
Delphi-Quellcode:
uses
Classes, uMainComponentInterface; type TServer = class(TPersistent) private fMainDingens : IMainDingens; function getHost : string; procedure setHost(const value : string); function getPort : Word; procedure setPort(const value : Word); published property Host : string read getHost write setHost; property Port : Word read getPort write setPort; public constructor Create(const owner : IMainDingens); end; implementation { TServer } constructor TServer.Create(const owner: IMainDingens); begin fMainDingens := owner; end; function TServer.getHost: string; begin result := fMainDingens.Host; end; function TServer.getPort: Word; begin result := fMainDingens.Port; end; procedure TServer.setHost(const value : string); begin fMainDingens.Host := value; end; procedure TServer.setPort(const value : Word); begin fMainDingens.Port := value; end;
Delphi-Quellcode:
Die beiden getter in der Komponente verdanken wir der zickigen Eigenart von Delphi-Interfaces, Properties nur mit vollen Zugriffsmethoden zuzulassen. (anstatt einfach property X : TType read write;)
uses
Classes, ScktComp, uServerAggregate, uMainComponentInterface; type TMainClass = class(TComponent, IMainDingens) private fClientSocket : TClientSocket; fServer : TServer; protected property ClientSocket : TClientSocket read fClientSocket implements IMainDingens; // vielen Dank dafür, dass man keine abstrakten Properties in Interfaces packen kann! :wall: function getPort : Integer; function getHost : string; published property Server : TServer read fServer write fServer; public procedure AfterConstruction; override; procedure BeforeDestruction; override; end; implementation { TMainClass } function TMainClass.getHost: string; begin Result := fClientSocket.Host; end; function TMainClass.getPort: Integer; begin Result := fClientSocket.Port; end; procedure TMainClass.AfterConstruction; begin inherited; fClientSocket := TClientSocket.Create(self); fServer := TServer.Create(self); end; procedure TMainClass.BeforeDestruction; begin inherited; fServer.Free(); fClientSocket.Free(); end; Deshalb können die Getter hier nicht zu TClientSocket delegiert werden. :wall: |
Re: Per Klasse auf übergeordnete Klasse zugreifen?
Die Frage scheint sich ja schon geklärt zu haben, trotzdem noch n alternativer Weg:
Delphi-Quellcode:
mfg
TMainClass = class(TComponent)
private FClientSocket: TClientSocket; FServer: TServer; procedure PropCh(<Parameter anpassen>); // Methode, die Socket-Properties anpasst public constructor Create(owner...); published Server: TServer read FServer write FServer; end; constructor TMainClass.Create(...); begin inherited...; ... FServer = TServer.Create; FServer.OnPropertyChange = PropCh; // OnPropertyChange in Setter-Metghoden aufrufen; dadurch wird PropCh aufgerufen end; procedure ProbCh; begin ... // ClientSocket ändern end; Christian |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:41 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