Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   OOP - Frage (https://www.delphipraxis.net/97948-oop-frage.html)

conti 19. Aug 2007 15:33


OOP - Frage
 
Habe folgendes Problem:
Delphi-Quellcode:
unit ServiceStarter;

constructor TServiceStarter.Create(service: TServiceInterface)
begin
 while ... do
 // für jeden Thread eine Instanz
   begin
    service := TServiceInterface.Create;
   end;
end;
In einer anderen Unit passiert dann das Folgende:
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

Der_Unwissende 19. Aug 2007 15:53

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

conti 19. Aug 2007 20:36

Re: OOP - Frage
 
Habe folgendes versucht:
Delphi-Quellcode:
  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;
Mein Ziel ist den Konstruktor der Kind-Klasse aufzurufen ... aber ich weiss nicht wie ich dass machen kann,
dabei kann ich in TFrame nur Objekte von Typ Basisklasse verwenden.


Würde mich auf eine Antwort freuen
Danke

mkinzler 19. Aug 2007 20:39

Re: OOP - Frage
 
Delphi-Quellcode:
c1 := TChild.Create;

conti 19. Aug 2007 20:48

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

mkinzler 19. Aug 2007 21:00

Re: OOP - Frage
 
Erweitere .Go um den Klassentyp.
Es gibt bereits eine Klasse TFrame in der VCL

DP-Maintenance 20. Aug 2007 05:18

DP-Maintenance
 
Dieses Thema wurde von "Matze" von "Programmieren allgemein" nach "Sonstige Fragen zu Delphi" verschoben.
Delphi-Frage

shmia 20. Aug 2007 12:11

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 10:37 Uhr.

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