AGB  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Mehrere Klassen von einer Klasse ableiten

Ein Thema von gargano · begonnen am 27. Apr 2012 · letzter Beitrag vom 30. Apr 2012
Antwort Antwort
Seite 1 von 3  1 23   
gargano

Registriert seit: 2. Okt 2006
69 Beiträge
 
Delphi 2007 Enterprise
 
#1

Mehrere Klassen von einer Klasse ableiten

  Alt 27. Apr 2012, 17:15
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:
if DeviceObject.ModuleName ='Manual Injectthen begin
  TManInjectDeviceDataModule(DeviceObject.DeviceModule).InitDevice;
end;

if DeviceObject.ModuleName ='Pump4xxthen begin
            TPump4xxDeviceDataModule(DeviceObject.DeviceModule).InitDevice;
end;

if DeviceObject.ModuleName ='Pump300/500then begin
            TPump35xxDeviceDataModule(DeviceObject.DeviceModule).InitDevice;
end;
DeviceObject ist auch eine Klasse, die dann das Object des jeweiligen Devices enthält.

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
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
24.778 Beiträge
 
Delphi XE Professional
 
#2

AW: Mehrere Klassen von einer Klasse ableiten

  Alt 27. Apr 2012, 17:28
Zitat:
Ich habe mehrere unterschiedliche Klassen die aber alle diegleichen Funktionen (im Interface) haben.
Die Klassen führen die Funktionen aber unterschiedlich aus.
Das klingt für mich, als bräuchtest Du eine (abstrakte) Basisklasse, von der die anderen dann abgeleitet werden.
Delphi-Quellcode:
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;
Je nachdem, von welchem Typ nun das übergebene Objekt ist, führt es dann die in der Ableitung implementierte Methode aus.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
36.134 Beiträge
 
Delphi XE6 Professional
 
#3

AW: Mehrere Klassen von einer Klasse ableiten

  Alt 27. Apr 2012, 17:29
Es würde imho auch ein Interface reichen
Markus Kinzler
  Mit Zitat antworten Zitat
gargano

Registriert seit: 2. Okt 2006
69 Beiträge
 
Delphi 2007 Enterprise
 
#4

AW: Mehrere Klassen von einer Klasse ableiten

  Alt 27. Apr 2012, 17:48
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.

Gruß
Gargano
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
24.778 Beiträge
 
Delphi XE Professional
 
#5

AW: Mehrere Klassen von einer Klasse ableiten

  Alt 27. Apr 2012, 20:25
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.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo
Online

Registriert seit: 5. Jan 2005
Ort: Stadthagen
6.830 Beiträge
 
Delphi 2010 Professional
 
#6

AW: Mehrere Klassen von einer Klasse ableiten

  Alt 27. Apr 2012, 20:54
Sprecht doch mal in ganzen Sätzen mit dem TE

Klassendefinition:
Delphi-Quellcode:
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.
Benutzung:
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;
Kaum macht man's richtig - schon funktioniert's
Nachdenkliche Menschen denken oft warum sie nicht schon vorher daran gedacht haben.
  Mit Zitat antworten Zitat
gargano

Registriert seit: 2. Okt 2006
69 Beiträge
 
Delphi 2007 Enterprise
 
#7

AW: Mehrere Klassen von einer Klasse ableiten

  Alt 28. Apr 2012, 08:29
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:
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;
Gruß
Gargano
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 16. Feb 2008
Ort: Baden-Württemberg
2.321 Beiträge
 
Delphi 2007 Professional
 
#8

AW: Mehrere Klassen von einer Klasse ableiten

  Alt 28. Apr 2012, 08:46
Wie kann ich also eine Klasse erzeugen, wenn ich diese nicht kenne ?
Deine Klasssen müssen sich im initialization Abschnitt mit Hier im Forum suchenRegisterClass() bekanntmachen.
Dann kannst du später mit Hier im Forum suchenFindClass() die Klasse finden und daraus neue Objekte erzeugen.
  Mit Zitat antworten Zitat
gargano

Registriert seit: 2. Okt 2006
69 Beiträge
 
Delphi 2007 Enterprise
 
#9

AW: Mehrere Klassen von einer Klasse ableiten

  Alt 28. Apr 2012, 11:41
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:
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.
Beim Aufruf von Button1Click im Main hat
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
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#10

AW: Mehrere Klassen von einer Klasse ableiten

  Alt 28. Apr 2012, 12:16
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) ;
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:53 Uhr.
Powered by vBulletin® Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2014 by Daniel R. Wolf