![]() |
Klasse die im Create eine Unterklasse erstellt
Hi alle,
ich habe zur Zeit das "Problem", dass ich eine Basisklasse habe von der mehrere Unterklassen (nennt man das eigentlich so?) abgeleitet sind. Dh sowas in der Art:
Delphi-Quellcode:
Nun muss ich ja im Programm Instanzen der Sub-Klassen erzeugen. Zur Zeit wüsste ich nur, dass ich direkt im normalen Code abfrage welchen Typ ich will und dann diese Klasse erstelle (zb MyCon := TSub1.Create;).
TBase = class
public constructor Create; override; end; TSub1 = class(TBase) public constructor Create; override; end; TSub2 = class(TBase) public constructor Create; override; end; Gibt es eine Möglichkeit, wie ich der Klasse TBase einen Konstruktor der Art Create(Typ: String); schreibe, der ich dann im Parameter zb "Sub1" übergebe, und die dann selber eine der Sub-Klassen erstellt? Also ungefähr sowas:
Delphi-Quellcode:
Wäre Klasse wenn das irgendwie ginge, oder jemand ne andre intelligente Art hat wie man sowas erledigt ;)
type
TBase = class public constructor Create(Typ: String); end; TSub1 = class public constructor Create; end; ... constructor TBase.Create(Typ: String); begin if Typ = 'Sub1' then Self := TSub1.Create; ... end; var MyClass = TBase; begin MyClass := TBase.Create('Sub1'); end; Grüße, Chris |
Re: Klasse die im Create eine Unterklasse erstellt
So etwas würde ich mit einer Klassenfunktion in der Basisklasse lösen:
Delphi-Quellcode:
Denn im Konstruktor kannst du nichts mehr ändern, da ist die Instanz schon erzeugt.
class function Erzeuge(Klasse: String): TBase;
Außerdem solltest du dieses String-Konzept nach Möglichkeit vermeiden, natürlich sofern du nicht den Namen vom Benutzer kriegst. Du solltest dir vielleicht mal Klassenreferenzen anschauen... |
Re: Klasse die im Create eine Unterklasse erstellt
Moin Chris,
irgendwie habe ich Dein Problem nicht verstanden. :gruebel: Wozu willst Du self etwas zuweisen? :shock: |
Re: Klasse die im Create eine Unterklasse erstellt
Die klasse TBase ist nicht zur Verwaltung der abgeleiteten Klassen TSub1 und TSub2 gedacht,
sondern ist eine Designvorlage für die beiden Klassen: TBase hat bestimmte properties die TSub1 und TSub2 auch besitzen. Du erweiterst TSub1 und TSub2 aber um bestimmte properties die die Basisklasse nicht besitzt. Frage ist was du genau bewirken willst. |
Re: Klasse die im Create eine Unterklasse erstellt
Grundsätzlich ist aber das Muster nicht falsch, z.B. kann so eine Erzeuger-Funktion recht nützlich sein, wenn man mit virtuellen Methoden arbeitet und durch Erstellung von verschiedenen Nachkommen eben entscheiden kann, welche virtuelle Methode aufgerufen wird.
|
Re: Klasse die im Create eine Unterklasse erstellt
Am Besten erzeugst du eine Variable nach dem Motto
Delphi-Quellcode:
Und entweder erzeugst du sie je nachdem was du brauchst:
var
MySub: TBase;
Delphi-Quellcode:
Oder du erzeugst sie als TBase und castest sie dynamisch
MySub:=TSub1.Create;
Delphi-Quellcode:
Da du aber nicht sagst was genau du machen möchtest können wir dir auch nicht sagen was die beste Lösung ist ;)
MySub:=TBase.Create;
(MySub as TSub1).EigenschaftVonSub1:=42; |
Re: Klasse die im Create eine Unterklasse erstellt
So, ich versuche mich auch mal dran...
Delphi-Quellcode:
Aufruf...
type
TModus = (Sub1, Sub2); TBase = class public constructor Create; overload; virtual; abstract; class function Create(Modus:TModus):TBase; overload; virtual; end; TSub1 = class(TBase) public constructor Create; override; end; TSub2 = class(TBase) public constructor Create; override; end; : : { TBase } class function TBase.Create(Modus:TModus): TBase; begin case Modus of Sub1: Result:=TSub1.Create; Sub2: Result:=TSub2.Create; end; end; { TSub1 } constructor TSub1.Create; begin inherited; end; { TSub2 } constructor TSub2.Create; begin inherited; end;
Delphi-Quellcode:
Gruss
procedure TForm.ButtonClick(Sender: TObject);
var Base:TBase; begin Base:=TBase.Create(Sub1); ShowMessage(Base.ClassName); Base:=TBase.Create(Sub2); ShowMessage(Base.ClassName); Base:=TBase.Create; // <-- löst einen "Abtrakten Fehler" aus ShowMessage(Base.ClassName); end; Thorsten |
Re: Klasse die im Create eine Unterklasse erstellt
Hi,
danke erstmal allen für die Tipps =) Die Idee mit der Klassenmethode scheint schonmal recht gut. Daran hab ich vorher nur irgendwie nie gedacht, hab auch in Delphi noch nie mit Klassen-methoden/attributen gearbeitet gehabt ;) @omata: Danke für dein Code-Schnipsel, denk mal genau so könnte es gut laufen =) @inherited: Zitat:
Hintergrund zu dem Ganzen: Ich habe ein Programm das über verschiedene Schnittstellen auf einen Bus zugreifen soll (RS232, USB, TCP/IP-Daemon, Modem). Dh dass die Klassen natürlich fast komplett identisch sind. Der einzige Unterschied besteht in den Konfigurationsparametern. Fände es halt da extrem unpraktisch wenn man im Programmcode dann immer die Abfragen machen müsste welche Klasse man grad braucht und die dann instanziiert, wenn das auch die Basis-Klasse selber übernehmen könnte =) Grüße, Chris |
Re: Klasse die im Create eine Unterklasse erstellt
Schnittstelle = Interface ;)
Warum definierst du nicht einfach ein Interface welches du in Interfaced Objects realisierst? etwa so (aus dem Stehgreif jetzt):
Delphi-Quellcode:
Jetzt kannst du diese InterfacedObjects auch als ISendMessage nutzen, weil sie das Interface ja realisieren und je nachdem WIE das Interface in den Klassen realisiert wird passiert evtl. etwas anderes.
type
ISendMessage = interface ['<GUID mit STRG+SHIFT+G erzeugen>'] procedure Send(const s: string); end; TTCPClass = class(TInterfacedObject, IMyInterface) procedure Send(const s: string); end; TUDPClass = class(TInterfacedObject, IMyInterface) procedure Send(const s: string); end; EDIT: wenn es ums erzeugen geht.. nimm eine Enumeration und eine Erzeuger-Funktion:
Delphi-Quellcode:
type TConnectionType = (ctTCP, ctUDP, ctRS232, {...}); {...} function CreateConnection(const contype: TConnectiontype): ISendMessage; begin case contype of ctUDP: Result := TUDPClass.Create; ctTCP: Result := TTCPClass.Create; else // evtl. Fehlermeldung end; end; |
Re: Klasse die im Create eine Unterklasse erstellt
Delphi-Quellcode:
Oder hab ich was missverstanden?
Type
TBase = Class...; TSub1 = Class (TBase)...; TSub2 = Class (TBase) ...; TBaseClass = Class Of TBase; Function CreateClass (aClass : TBaseClass) : TBase; Begin Result := aClass.Create End; Du solltest Dir eine ClassFactory bauen. Das ist eine Klasse, die dir genau die richtigen Instanzen erzeugt, im Grunde genommen aber nichts anderes als die 'CreateClass'-Funktion ist, nur eben als Klasse.
Delphi-Quellcode:
In der TBase-Klasse kannst Du schon rein konzeptionell keine Funktion implementieren, die Nachkommen von TBase erzeugt. TBase kann doch gar nicht wissen, was für Nachkommen auf der Welt existieren? Was ist, wenn jemand in Timbuktu von deiner TBase-Klasse ableitet? Wie soll er dann noch die TBase-Klasse ändern? Hat er immer den Quellcode parat? Dazu ist doch der ganze Vererbungsquatsch da, um eben *nicht* mehr in Basisklassen rumzufuhrwerken, wenn eine neue Ableitung hinzukommt. :gruebel:
Type
TBaseFactory = Class Public Function CreateClass (aClass : TBaseClass) : TBase; End; Der obige Code mit Klassenreferenzen funktioniert immer und wird es auch immer. Wenn neue, von TBase abgeleitete Klassen hinzukommen, musst Du da gar nichts mehr ändern. Keine Enumeration hinzufügen, nix. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:11 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