![]() |
OOP - Frage
Habe folgendes Problem:
Delphi-Quellcode:
In einer anderen Unit passiert dann das Folgende:
unit ServiceStarter;
constructor TServiceStarter.Create(service: TServiceInterface) begin while ... do // für jeden Thread eine Instanz begin service := TServiceInterface.Create; end; end;
Delphi-Quellcode:
srvStarter: TServiceStarter;
service1: TService1; // TService1 ist von TServiceInterface abgeleitet!! //... srvStarter := TServiceStarter.Create(service1); Jeder Service ist von TServiceInterface abgeleitet (natürlich macht jeder Service immer etwas extra dazu ...) Der ServiceStarter muss mitjedwelchen klar kommen! Aber dazu muss ich die Generalität behalten, also in der Unit ServiceStarter mit der BasisKlasse (TServiceInterface) arbeiten. Die Folge ist, dass ich nur den Konstruktor der Basisklasse aufrufen kann ... dabei bräuchte ich für jeden Service den eigenen Konstruktor aufzurufen. Ich hoffe, dass ich das ganze richtig beschrieben habe ... vielleicht könnte jemand mit ein paar Ratschlägen helfen! Danke |
Re: OOP - Frage
Das Problem, dass Du bei der Implementierung hast ist, dass Du hier nur parameterlose Konstruktoren gut aufrufen kannst. Die Lösung für den Fall ist eigentlich recht einfach, Du erzeugst so wie Du es schon machst ein neues Exemplar (mit dem Konstruktor der Basisklasse) und rufst dann eine spezielle Init-Methode auf. Diese enthält dann einfach den Code, der für die jeweilige Klasse spezifisch ist. Für die Basisklasse kannst Du dabei diese Methode als virtual; abstract; deklarieren und in den abgeleiteten Klassen überschreiben (override). Damit wird immer die Methode aufgerufen, die zur tatsächlich übergebenen Klasse gehört.
Etwas problematischer ist es, wenn Du die Konstruktoren zusätzlich mit Argumenten aurufen möchtes, diese müsstest Du also dyn. Struktur übergeben. Dafür kommt ein Array of const in Frage (weiß gerade nicht mehr wie die heißen) oder eben auch eine TList oder Ähnliches. Die Init-Methode müsste eben entsprechend angepasst und TServiceStarter.Create um dieses zusätzliche Argument erweitert werden. Die Anzahl der tatsächlichen Argumente und deren Typ ist dann wieder für jede Klasse bekannt, kann also problemlos aus der Struktur extrahiert werden. Gruß Der Unwissende |
Re: OOP - Frage
Habe folgendes versucht:
Delphi-Quellcode:
Mein Ziel ist den Konstruktor der Kind-Klasse aufzurufen ... aber ich weiss nicht wie ich dass machen kann,
TMain = class(TObject)
public constructor create; procedure init; virtual; abstract; end; TChild = class(TMain) public constructor Create; procedure init; override; end; TFrame = class(TObject) public procedure Go(obj: TMain); end; var Form1: TForm1; c1: TChild; // c1 von Typ TChild implementation constructor TMain.create; begin inherited; showMessage('Main'); end; constructor TChild.Create; begin inherited; showMessage('Child'); end; procedure TChild.init; begin // inherited; self.Create; end; procedure TFrame.Go(obj: TMain); begin obj := TMain.create; obj.init; end; procedure TForm1.Button1Click(Sender: TObject); begin TFrame.Create.Go(c1); // c1 ist von Typ TChild end; dabei kann ich in TFrame nur Objekte von Typ Basisklasse verwenden. Würde mich auf eine Antwort freuen Danke |
Re: OOP - Frage
Delphi-Quellcode:
c1 := TChild.Create;
|
Re: OOP - Frage
(das obere sollte nur das Problem einfach schildern)
... das Problem ist nur: Ich weiss in TFrame nichts über TChild (es könnte TChild1, TChild2, TChild3, usw sein) darum verwende ich den Konstruktor aus der Basisklasse ... Vieleicht sehe ich ja die ganze Sache falsch ... darum wollte ich ja um Rat fragen Könnte jemand mit eine Idee hinzufügen??? Danke conti |
Re: OOP - Frage
Erweitere .Go um den Klassentyp.
Es gibt bereits eine Klasse TFrame in der VCL |
DP-Maintenance
Dieses Thema wurde von "Matze" von "Programmieren allgemein" nach "Sonstige Fragen zu Delphi" verschoben.
Delphi-Frage |
Re: OOP - Frage
Damit der richtige Konstruktor aufgerufen wird, muss dieser virtuell sein.
Zusätzlich braucht man aber auch einen Klassenreferenztyp (class of).
Delphi-Quellcode:
unit ServiceStarter;
type TServiceClass = class of TServiceInterface; constructor TServiceStarter.Create(service: TServiceClass; var obj: TServiceInterface) begin while ... do // für jeden Thread eine Instanz begin service := service.Create; end; end; srvStarter: TServiceStarter; service1: TService1; // TService1 ist von TServiceInterface abgeleitet!! //... srvStarter := TServiceStarter.Create(TService1, service1); |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:45 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