![]() |
Delphi-Version: XE2
Klasse nach Vergleich mit Feld in Klasse erzeugen
Hallo,
ich habe mehrere Klassen, die von einer abstrakten Klasse geerbt haben. Ich muss nun je nach Eingabewert unterscheiden, welche dieser Childklassen erzeugt werden und mit dem Ergebnis arbeiten. Ob diese Klasse das Ergebnis verarbeiten kann steht in der Klasse als Eigenschaft. Ich habe hier versucht, zumindest teiwleise das Strategie Pattern umzusetzen. Codebeispiel:
Delphi-Quellcode:
Ich habe etwas von Methodenklassen gelesen, wäre dies der WEg zu Ziel, oder gibt es andere Lösungen?
type TParentClass = class
{iwas} end; type TChildclass(TParentclass) eineZahl: Integer; procedure eineMethode(asd: String); end; procedure choose; var EineChildclass: TChildclass; begin If eineChildclass.eineZahl = 1 then begin EineChildclass := TChildclass.Create; EineChildclass.eineMethode('test'; // WIe frage ich ab, welche Klasse erzeugt werden muss? end; end; |
AW: Klasse nach Vergleich mit Feld in Klasse erzeugen
Ich weiß nicht, ob es nur mir so geht, aber ich verstehe weder die Frage noch Deinen Code so richtig. Wie kannst Du ein Feld einer Instanz abfragen, die Du im Anschluss erst erzeugst?
|
AW: Klasse nach Vergleich mit Feld in Klasse erzeugen
Das genau ist ja der Knackpunkt. Ich möchte die Eigenschaft gerne in der Klasse kapseln, muss aber auch wissen, welche klasse ich nun genau benutzen muss. Der vergleiswert ist variabel, deswegen dieser umständliche weg.
|
AW: Klasse nach Vergleich mit Feld in Klasse erzeugen
Suchst Du eine Class Function eineZahl ??
|
AW: Klasse nach Vergleich mit Feld in Klasse erzeugen
RTTI? Ich verstehe immer noch nicht ganz, was eigentlich die Anforderung ist, sry.
|
AW: Klasse nach Vergleich mit Feld in Klasse erzeugen
ich vermute er such so etwas
Delphi-Quellcode:
unit Unit2;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,jpeg, StdCtrls, ExtCtrls; type TMasterClass=Class Class Function WasKannich:Integer;virtual; End; TMasterChildClass1=Class(TMasterClass) Class Function WasKannich:Integer;override; End; TMasterChildClass2=Class(TMasterClass) Class Function WasKannich:Integer;override; End; TMasterClassClass=Class of TMasterClass ; TForm2 = class(TForm) Button1: TButton; Image1: TImage; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form2: TForm2; implementation {$R *.dfm} procedure TForm2.Button1Click(Sender: TObject); var CK:TMasterClassClass; begin if TMasterChildClass1.WasKannich=2 then CK := TMasterChildClass1 else if TMasterChildClass2.WasKannich=2 then CK := TMasterChildClass2; With CK.Create do begin Showmessage(IntToStr(WasKannich)); Free; end; end; { TMasterChildClass2 } class function TMasterChildClass2.WasKannich: Integer; begin Result := 2; end; { TMasterChildClass1 } class function TMasterChildClass1.WasKannich: Integer; begin Result := 1; end; { TMasterClass } class function TMasterClass.WasKannich: Integer; begin Result := 0; end; end. |
AW: Klasse nach Vergleich mit Feld in Klasse erzeugen
1.) die Basisklasse hat eine statische Methoden (in Delphi Klassenmethode genannt)
mit der man Abfragen kann ob eine Klasse bestimmte Eigenschaften hat bzw. über bestimmte Features verfügt. 2.) die Klassenmethode sollte virtuell sein; das bietet noch mehr Möglichkeiten
Delphi-Quellcode:
3.) eine Factorymethode erzeugt aufgrund der gewünschten Features ein Objekt einer konkreten (Child-)Klasse:
type
TParentClass = class public class function HasFeature(const name:string):boolean;virtual; end; TChildclass = class(TParentclass) class function HasFeature(const name:string):boolean;override; end; class function TChildclass.HasFeature(const name:string):boolean; begin // die konkrete Klasse unterstützt die Features Secure und Hip result := (name='Secure') or (name='hip'); end;
Delphi-Quellcode:
Man kann auch mehrere Features prüfen um die passende Klasse zu finden.
function TMyFactory.CreateObject(const feature:string):TParentClass;
begin if TChildclass1.HasFeature(feature) then result := TChildclass1.Create else if TChildclass2.HasFeature(feature) then result := TChildclass2.Create ... else result := nil; end; Anstatt jede einzelne Klasse zu testen kann man auch alle registrierten Klassen in einer Schleife testen (aber dazu benötigt man fortgeschrittene Techniken, die ich im Moment nicht erklären möchte) PS: der Bummi war natürlich mal wieder schneller |
AW: Klasse nach Vergleich mit Feld in Klasse erzeugen
@shmia
tschuldigkeit :oops: sonst schlägt mich immer DeddyH .... |
AW: Klasse nach Vergleich mit Feld in Klasse erzeugen
Ja genau das habe ich gesucht. Danke an alle für die schnelle Hilfe :)
|
AW: Klasse nach Vergleich mit Feld in Klasse erzeugen
Mit der neuen erweiterten RTTI kann man auch Attribute anlegen und auslesen, zu den Klassentypen (quasi ähnlich der virtuellen Klassenmethoden).
|
AW: Klasse nach Vergleich mit Feld in Klasse erzeugen
Ja eben, nach einem Blick auf sein Profil fiel mir auch gleich RTTI ein, da muss man dann nicht soviel selbst machen.
|
AW: Klasse nach Vergleich mit Feld in Klasse erzeugen
Im Prinzip muss die Factory die zu erzeugenden Klassen nicht einmal konkret kennen.
So kann man später beliebige Unterklassen ableiten, ohne TParentClass zu ändern:
Delphi-Quellcode:
unit UnitParentClass;
interface uses Classes, Contnrs, SysUtils; type TChildClassParams = record {...} end; TParentClass = class; TChildClassType = class of TParentClass; TParentClass = class private class var FClassList: TClassList; class procedure FreeList; protected class procedure Register(AClassType: TChildClassType); class function New(AParams: TChildClassParams; var AInstance: TParentClass): Boolean; virtual; abstract; public class function CreateInstance(AParams: TChildClassParams): TParentClass; end; implementation { TParentClass } class function TParentClass.CreateInstance(AParams: TChildClassParams): TParentClass; var p: Pointer; begin Result := nil; if Assigned(FClassList) then begin for p in FClassList do begin if TChildClassType(p).New(AParams, Result) then Exit; end; end; end; class procedure TParentClass.FreeList; begin FreeAndNil(FClassList); end; class procedure TParentClass.Register(AClassType: TChildClassType); begin if not Assigned(FClassList) then FClassList := TClassList.Create; FClassList.Add(AClassType); end; initialization finalization TParentClass.FreeList; end.
Delphi-Quellcode:
unit UnitChildClass;
interface uses UnitParentClass; type TChildClass = class(TParentClass) protected class function New(AParams: TChildClassParams; var AInstance: TParentClass): Boolean; override; end; implementation { TChildClass } class function TChildClass.New(AParams: TChildClassParams; var AInstance: TParentClass): Boolean; begin Result := {AParams = ???} True; if Result then AInstance := Self.Create; end; initialization TChildClass.Register(TChildClass); end. |
AW: Klasse nach Vergleich mit Feld in Klasse erzeugen
Zitat:
|
AW: Klasse nach Vergleich mit Feld in Klasse erzeugen
Du kannst deine Klassen bei einer generischen
Delphi-Quellcode:
registrieren und dann diese durchsuchen.
TList<TChildClassType>
Man könnte auch z.B. ein
Delphi-Quellcode:
nutzen, wo dann der der "Schlüssel" nicht in der Klasse steht, sondern in der Liste.
TDictionary<string, TChildClassType>
Dort würde dann eine einzige Suchanfrage an diese Liste sofort die Klasse liefern. |
AW: Klasse nach Vergleich mit Feld in Klasse erzeugen
Zitat:
Jede Child-Klasse muss zunächst registriert werden. Er hat dann aber einen etwas indirekten Weg über die virtuelle Methode New eingeschlagen um ein Objekt einer bestimmten Klasse zu erzeugen. Der Standardweg wäre aber einen virtuellen Konstruktor in der Basisklasse einzuführen, der dann in allen Child-Klassen überschrieben werden muss. So macht es z.B. die VCL mit der Klasse TComponent. Der Konstruktor ist virtuell damit zur Laufzeit immer der richtige Code ausgeführt wird. Die hat aber zur Konsequenz dass es nur noch einen Konstruktor geben darf. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:39 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