![]() |
Mehrere Klassen von einer Klasse ableiten
Hallo,
ich habe schon einiges hier von abstrakten Klasse, Interfaces, Plugins gelesen, bin aber nicht so richtig fündig geworden. Mein Problem ist folgendes: Ich habe mehrere unterschiedliche Klassen die aber alle diegleichen Funktionen (im Interface) haben. Die Klassen führen die Funktionen aber unterschiedlich aus. Um auf die verschiedenen Klassen zuzugreifen habe ich im Moment eine Verzweigungsroutine z.B:
Delphi-Quellcode:
DeviceObject ist auch eine Klasse, die dann das Object des jeweiligen Devices enthält.
if DeviceObject.ModuleName ='Manual Inject' then begin
TManInjectDeviceDataModule(DeviceObject.DeviceModule).InitDevice; end; if DeviceObject.ModuleName ='Pump4xx' then begin TPump4xxDeviceDataModule(DeviceObject.DeviceModule).InitDevice; end; if DeviceObject.ModuleName ='Pump300/500' then begin TPump35xxDeviceDataModule(DeviceObject.DeviceModule).InitDevice; end; Mein Problem ist jetzt, das wenn eine neue Klasse hinzukommt ich jedesmal diese Verzweigungsroutinen ändern muß. Ziel ist es, eine Liste zu haben ( die man erweitern kann) in der die Namen der Bpl's stehen und diese bpl (für jedes Device eine eigene Bpl) dynamisch geladen wird. In diesem Falle ist diese Verzweigung nicht mehr nötig, sodaß das Hauptprogramm nicht jedesmal neu kompiliert werden muß. Es müßte also anhand des Modulnamens auf die richtige Klasse zugegriffen werden. Die Klasse muß auch mehrfach instanziiert werden können. Wie kann ich das am besten und einfachsten bewerkstelligen ? Gruß Gargano |
AW: Mehrere Klassen von einer Klasse ableiten
Zitat:
Delphi-Quellcode:
Je nachdem, von welchem Typ nun das übergebene Objekt ist, führt es dann die in der Ableitung implementierte Methode aus.
type
TBaseClass = class protected procedure DoSomethingImportant; virtual; abstract; procedure DoSomethingMoreImportant; virtual; abstract; procedure DoSomethingEvenMoreImportant; virtual; abstract; end; TFirstChild = class(TBaseClass) protected procedure DoSomethingImportant; override; procedure DoSomethingMoreImportant; override; procedure DoSomethingEvenMoreImportant; override; end; TSecondChild = class(TBaseClass) protected procedure DoSomethingImportant; override; procedure DoSomethingMoreImportant; override; procedure DoSomethingEvenMoreImportant; override; end; procedure TMain.DoSomething(AObject: TBaseClass); begin AObject.DoSomethingImportant; end; |
AW: Mehrere Klassen von einer Klasse ableiten
Es würde imho auch ein Interface reichen
|
AW: Mehrere Klassen von einer Klasse ableiten
Hallo DeddyH,
danke für die Antwort. Bleibt das Problem, daß ich den Klassentyp von AObject nicht weiß , da der Typ ja in der Bpl enthalten ist und diese erst zur Laufzeit geladen wird. Kann ich den Typ zur Laufzeit ermitteln ? Wie wäre dann der Aufruf von TMain.DoSomething(AObject:TBaseClass) ? mkinzler : Von Interfaces habe ich gelesen, daß diese mit Memoryleaks Probleme haben.... Die Applikation steuert verschiedene Analysengeräte und darf nicht ausfallen. :roll: Gruß Gargano |
AW: Mehrere Klassen von einer Klasse ableiten
Du kannst den Typ schon zur Laufzeit ermitteln (if Dings is TBums), aber wozu? Dadurch, dass Du die Basisklasse als Datentyp übergibst (und dann ein Objekt einer davon abgeleiteten), kannst Du Dir sicher sein, dass das Objekt die richtige Methode ausführt. Zumindest, solange diese Methode überschrieben (override) wurde und nicht verdeckt. Möglicherweise verstehe ich Dich aber auch falsch.
|
AW: Mehrere Klassen von einer Klasse ableiten
Sprecht doch mal in ganzen Sätzen mit dem TE ;)
Klassendefinition:
Delphi-Quellcode:
Benutzung:
unit DeviceUnit;
interface type TBaseDevice = class procedure InitDevice; virtual; abstract; end; TMainDevice = class( TBaseDevice ) procedure InitDevice; override; end; TSubDevice = class( TBaseDevice ) procedure InitDevice; override; end; implementation procedure TMainDevice.InitDevice; begin ShowMessage('MainDevice initialisiert'); end; procedure TSubDevice.InitDevice; begin ShowMessage('SubDevice initialisiert'); end; end.
Delphi-Quellcode:
uses
DeviceUnit; procedure DoSomething( aDevice : TBaseDevice ); begin aDevice.InitDevice; end; procedure Test1; var MyMainDevice : TMainDevice; MySubDevice : TSubDevice; begin MyMainDevice := TMainDevice.Create; try DoSomething( MyMainDevice ); // -> MsgBox mit 'MainDevice initialisiert' finally MyMainDevice.Free; end; MySubDevice := TSubDevice.Create; try DoSomething( MySubDevice ); // -> MsgBox mit 'SubDevice initialisiert' finally MySubDevice.Free; end; end; procedure Test2; var MyDevice : TBaseDevice; begin MyDevice := TMainDevice.Create; try DoSomething( MyDevice ); // -> MsgBox mit 'MainDevice initialisiert' finally MyDevice.Free; end; MyDevice := TSubDevice.Create; try DoSomething( MyDevice ); // -> MsgBox mit 'SubDevice initialisiert' finally MyDevice.Free; end; end; |
AW: Mehrere Klassen von einer Klasse ableiten
Hallo zusammen,
danke für die Antwort und das Beispiel. Allerdings hat dies einen Haken: Man muß beim Kompilieren den Klassentyp kennen , hier den TMainDevice oder TSubDevice. Nur die Klassen sind im Hauptprogramm nicht bekannt beim Kompilieren. Nochmal zur Erklärung : Es werden Devicemodule entwickelt, die zur Laufzeit dynamisch als bpl geladen werden (Pro Devicemodule eine Bpl) . Die Klassen in dieser bpl sind aber dem Hauptprogramm zum Zeitpunkt der Kompilierung nicht bekannt. Also angenommen, man definiert ein neues Devicemodule mit TXDevice als Klasse. TXDevice ist in einer bpl eingebunden. Zur Laufzeit wird die Bpl dynamisch geladen. Welche bpl geladen wird ist in einem Ascii File eingetragen, der die Namen der bpl's enthält. Dies geschieht alles ohne das Hauptprogramm neu zu kompilieren. Wie kann ich nun in dem untenstehenden Beispiel TXDevice erzeugen ? Wie kann ich also eine Klasse erzeugen, wenn ich diese nicht kenne ? Oder sollte man hier ganz anders vorgehen ? In dem untenstehenden Beispiel wäre dies dann so,wenn man bei abstraken Methoden bleibt :
Delphi-Quellcode:
Gruß
procedure Test2;
var MyDevice : TBaseDevice; begin // TMainDevice ist hier nicht bekannt, es kann auch TXDevice // sein oder anders. MyDevice := TMainDevice.Create; try DoSomething( MyDevice ); // -> MsgBox mit 'MainDevice initialisiert' finally MyDevice.Free; end; Gargano |
AW: Mehrere Klassen von einer Klasse ableiten
Zitat:
Delphi-Quellcode:
Abschnitt mit
initialization
![]() Dann kannst du später mit ![]() |
AW: Mehrere Klassen von einer Klasse ableiten
Hallo Zusammen,
jetzt habe ich mal versucht das ganze in Code umzuwandeln Ich habe die Unit Main (Hauptprogramm), BaseUnit (abstrakte Klasse) und Unit1 (DeviceModule1). Main :
Delphi-Quellcode:
Beim Aufruf von Button1Click im Main hat
unit Main;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, BaseUnit; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } MyDevice : TBaseClass; end; var Form1: TForm1; implementation uses Unit1; {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin MyDevice:=TBaseClass(FindClass('TDeviceModule1')); TBaseClass(MyDevice).Create(Self); end; end. BaseUnit: unit BaseUnit; interface uses SysUtils, Classes; type TBaseClass = class (TDataModule) protected procedure DoSomethingImportant; virtual; abstract; procedure DoSomethingMoreImportant; virtual; abstract; procedure DoSomethingEvenMoreImportant; virtual; abstract; end; implementation end. Unit1: unit Unit1; interface uses SysUtils, Classes,Forms,BaseUnit; type TDeviceModule1 = class(TBaseClass) procedure ShowMsg (Msg:String); procedure DataModuleCreate(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var DeviceModule1: TDeviceModule1; implementation {$R *.dfm} procedure TDeviceModule1.DataModuleCreate(Sender: TObject); begin ShowMsg('Create'); end; procedure TDeviceModule1.ShowMsg (Msg:String); begin Application.MessageBox(PChar(Msg),'Module1'); end; initialization RegisterClasses([TDeviceModule1]); end. MyDevice dann diesen Wert in der Liste der überwachten Ausdrücke : ([csSubComponent..csTransient,(außerhalb der zulässigen Bereichs) 5..(außerhalb der zulässigen Bereichs) 7]) Beim Aufruf von TBaseClass(MyDevice).Create(Self) im Main kommt es zu einer Exception. Warum ? Gruß Gargano |
AW: Mehrere Klassen von einer Klasse ableiten
Du benötigst noch TBaseClassClass=Class of TBaseClass;
Beispiel:
Delphi-Quellcode:
var
c:TControl; begin C := TControlClass(FindClass('TButton')).Create(Self); C.Parent := Self; C.Width := 100; C.Height := 100; end; initialization Registerclass(TButton) ; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:29 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 by Thomas Breitkreuz