AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Klasse die im Create eine Unterklasse erstellt
Thema durchsuchen
Ansicht
Themen-Optionen

Klasse die im Create eine Unterklasse erstellt

Ein Thema von Alloc · begonnen am 22. Nov 2007 · letzter Beitrag vom 23. Nov 2007
Antwort Antwort
Seite 1 von 2  1 2      
Alloc

Registriert seit: 18. Apr 2005
Ort: Griesheim
167 Beiträge
 
Delphi 2006 Professional
 
#1

Klasse die im Create eine Unterklasse erstellt

  Alt 22. Nov 2007, 20:13
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:
TBase = class
  public
    constructor Create; override;
end;

TSub1 = class(TBase)
  public
    constructor Create; override;
end;

TSub2 = class(TBase)
  public
    constructor Create; override;
end;
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.
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:
type
  TBase = class
    public
      constructor Create(Typ: String);
  end;
  TSub1 = class
    public
      constructor Create;
  end;
 ...

constructor TBase.Create(Typ: String);
begin
  if Typ = 'Sub1then
    Self := TSub1.Create;
  ...
end;

var
  MyClass = TBase;
begin
  MyClass := TBase.Create('Sub1');
end;
Wäre Klasse wenn das irgendwie ginge, oder jemand ne andre intelligente Art hat wie man sowas erledigt

Grüße,
Chris
Christian Illy
ONI2.net, basicly every important link about Oni.
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: Klasse die im Create eine Unterklasse erstellt

  Alt 22. Nov 2007, 20:17
So etwas würde ich mit einer Klassenfunktion in der Basisklasse lösen:
class function Erzeuge(Klasse: String): TBase; Denn im Konstruktor kannst du nichts mehr ändern, da ist die Instanz schon erzeugt.

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...
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.117 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: Klasse die im Create eine Unterklasse erstellt

  Alt 22. Nov 2007, 20:20
Moin Chris,

irgendwie habe ich Dein Problem nicht verstanden.
Wozu willst Du self etwas zuweisen?
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Benutzerbild von semo
semo

Registriert seit: 24. Apr 2004
755 Beiträge
 
Delphi 2010 Professional
 
#4

Re: Klasse die im Create eine Unterklasse erstellt

  Alt 22. Nov 2007, 20:46
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.
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#5

Re: Klasse die im Create eine Unterklasse erstellt

  Alt 22. Nov 2007, 20:49
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.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Benutzerbild von inherited
inherited

Registriert seit: 19. Dez 2005
Ort: Rosdorf
2.022 Beiträge
 
Turbo Delphi für Win32
 
#6

Re: Klasse die im Create eine Unterklasse erstellt

  Alt 22. Nov 2007, 22:28
Am Besten erzeugst du eine Variable nach dem Motto
Delphi-Quellcode:
var
  MySub: TBase;
Und entweder erzeugst du sie je nachdem was du brauchst:
  MySub:=TSub1.Create; Oder du erzeugst sie als TBase und castest sie dynamisch
Delphi-Quellcode:
  MySub:=TBase.Create;
  (MySub as TSub1).EigenschaftVonSub1:=42;
Da du aber nicht sagst was genau du machen möchtest können wir dir auch nicht sagen was die beste Lösung ist
Nikolai Wyderka

SWIM SWIM HUNGRY!
Neuer Blog: hier!
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#7

Re: Klasse die im Create eine Unterklasse erstellt

  Alt 23. Nov 2007, 00:10
So, ich versuche mich auch mal dran...

Delphi-Quellcode:
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;
Aufruf...
Delphi-Quellcode:
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;
Gruss
Thorsten
  Mit Zitat antworten Zitat
Alloc

Registriert seit: 18. Apr 2005
Ort: Griesheim
167 Beiträge
 
Delphi 2006 Professional
 
#8

Re: Klasse die im Create eine Unterklasse erstellt

  Alt 23. Nov 2007, 01:01
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:
Delphi-Quellcode:
var
  MySub: TBase;
...
Oder du erzeugst sie als TBase und castest sie dynamisch
Delphi-Quellcode:
  MySub:=TBase.Create;
  (MySub as TSub1).EigenschaftVonSub1:=42;
Kann das funktionieren? Wenn ich mit MySub := TBase.Create; eine Instanz von TBase erstelle, kann ich doch schlecht auf eine Eigenschaft einer Sub-Klasse zugreifen, da es ja eben eine Instanz von TBase ist?!


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
Christian Illy
ONI2.net, basicly every important link about Oni.
  Mit Zitat antworten Zitat
Benutzerbild von cruiser
cruiser

Registriert seit: 23. Dez 2003
Ort: Königsbrück/Sachsen
455 Beiträge
 
Delphi 7 Enterprise
 
#9

Re: Klasse die im Create eine Unterklasse erstellt

  Alt 23. Nov 2007, 05:35
Schnittstelle = Interface

Warum definierst du nicht einfach ein Interface welches du in Interfaced Objects realisierst?

etwa so (aus dem Stehgreif jetzt):
Delphi-Quellcode:
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;
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.

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;
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#10

Re: Klasse die im Create eine Unterklasse erstellt

  Alt 23. Nov 2007, 08:37
Delphi-Quellcode:
Type
  TBase = Class...;
  TSub1 = Class (TBase)...;
  TSub2 = Class (TBase) ...;

  TBaseClass = Class Of TBase;


Function CreateClass (aClass : TBaseClass) : TBase;
Begin
  Result := aClass.Create
End;
Oder hab ich was missverstanden?

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:
Type
  TBaseFactory = Class
  Public
     Function CreateClass (aClass : TBaseClass) : TBase;
  End;
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.

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.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:33 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