Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Klasse sich selbst in eine abgeleitete konvertieren (https://www.delphipraxis.net/148396-klasse-sich-selbst-eine-abgeleitete-konvertieren.html)

Patrick 1. Mär 2010 10:53


Klasse sich selbst in eine abgeleitete konvertieren
 
Hallo,

ich habe eine abstrakte Klasse, die im Konstruktor ermittelt um welche Konkrete Klasse es sich handelt. Kann ich das irgendwie bewerkstelligen, dass sie sich nun selbst in die konkrete Klasse konvertiert? Der konstruierenden Instanz sollte es eigentlich egal sein, welche konkrete Klasse erzeugt wird. Somit muss es diese selbst bewerkstelligen.

Lange Rede kurzer Sinn, ich will einfach eine Klasse sich selbst upgraden lassen:

z.B.
in einer Methode "Aufrüsten"
TTransporter wird zu TSchweineTransporter.
(TSchweineTransporter ist von TTransporter abgeleitet)

Phoenix 1. Mär 2010 11:04

Re: Klasse sich selbst in eine abgeleitete konvertieren
 
Das klingt ein bisschen Wirr.

Meinst Du vielleicht das sogenannte Factory-Pattern?

Ansonsten macht die Geschichte nicht viel Sinn: Die abstrakte Basisklasse kann den eigentlichen Typen gar nicht kennen.

Man stelle sich vor, die abstrakte Basisklasse liegt in einem Package, ein anderer Entwickler verwendet das Package und leitet von ihr ab - z.B. von TTransporter auf THühnerTransporter. Diese Klasse liegt dann in einem Package, das von Deinem Package abhängt. Deine Basisklasse wird daher nie alle seine Ableitungen kennen und dorthin casten können.

Das eigentliche Objekt ist im übrigen immer vom konkreten Typ. Das heisst wenn eine methode zwangsläufig einen Schweinetransporter braucht und nur einen Transporter erhält, dann muss sie sich selber drum kümmern zu gucken ob da Schweine reinpassen und ihn nötigenfalls zum Schweinetransporter runtercasten.

Patrick 1. Mär 2010 11:29

Re: Klasse sich selbst in eine abgeleitete konvertieren
 
An das Factory-Pattern habe ich auch gedacht. Aber dann hätte ja die Factory auch über das Wissen verfügen müssen, wie Entschieden wird welche konkrete Klasse im Endeffekt erstellt werden muss.
Ich habe nun eine Methode gefunden, wie nur die eine abstrakte Klasse das wissen muss. Und in meinem Fall muss die abstrakte Klasse nicht alle Ableitungen kennen. Ich arbeite mit "GetClass(string)"

Delphi-Quellcode:
var Transporter : TTransporter;
Transporter := TTransporter.CreateInstanz('TSchweineTransporter');
Delphi-Quellcode:
class function TTransporter.CreateInstanz(EntryValue: string): TTransporter;
var tmp : TPersistentClass;
begin
  tmp := GetClass(EntryValue);
  if not Assigned(tmp) or tmp.InheritsFrom(TTransporter) then
  begin
    Result := nil;
    raise Exception.Create('Fehler!');
  end
  else
    Result := TTransporter(tmp);
end;

Tyrael Y. 1. Mär 2010 12:08

Re: Klasse sich selbst in eine abgeleitete konvertieren
 
Ich habe das Gefühl du möchtest Interfaces einsetzen.

Interfaces

guinnes 1. Mär 2010 12:14

Re: Klasse sich selbst in eine abgeleitete konvertieren
 
Was hältst du von Klassenreferenztypen :
Zitat:

Klassenreferenztypen werden auch als Metaklassen bezeichnet. Die Definition erfolgt folgendermaßen:

class of Typ

Typ ist ein beliebiger Klassentyp. Der Bezeichner Typ gibt einen Wert des Typs class of Typ an. Ist Typ1 ein Vorfahr von Typ
2, dann ist class of Typ2 zuweisungskompatibel zu class of Typ1. Ein Beispiel:

type TClass = class of TObject;

var AnyObj: TClass;

Die Variable AnyObj kann eine beliebige Klassenreferenz aufnehmen (ein Klassenreferenztyp darf nicht direkt in einer Variablendeklaration oder Parameterliste definiert werden). Klassenreferenzvariablen kann auch der Wert nil zugewiesen werden.
Das folgende Beispiel (Konstruktor der Klasse TCollection in der Unit Classes) zeigt, wie Klassenreferenztypen verwendet werden:

type TCollectionItemClass = class of TCollectionItem;

...
constructor Create(ItemClass: TCollectionItemClass);

Diese Deklaration besagt, daß beim Erstellen eines TCollection-Instanzobjekts der Name einer von TCollectionItem abgeleiteten Klasse an den Konstruktor übergeben werden muß.
Klassenreferenztypen sind hilfreich, wenn Sie eine Klassenmethode oder einen virtuellen Konstruktor in einer Klasse oder einem Objekt aufrufen wollen, dessen aktueller Typ zur Compilierzeit nicht bekannt ist.

uligerhardt 1. Mär 2010 12:32

Re: Klasse sich selbst in eine abgeleitete konvertieren
 
Vielleicht kannst du Aggregation statt Vererbung benutzen? Also den Teil der Funktionalität, der "aufgerüstet" werden muss, in eine eigene, nicht von TTransporter abgeleitete Klassenhierachie auslagern, und eine passende Klasse instantiieren. TTransporter hätte also eine Referenz auf (z.B.) TTransporterVerhalten, die du z.B. auf eine Instanz von TSchweineTransporterVerhalten zeigen lässt.

Patrick 1. Mär 2010 13:19

Re: Klasse sich selbst in eine abgeleitete konvertieren
 
Klassenrefenzen benutze ich ja quasi schon.
Delphi-Quellcode:
tmp : TPersistentClass;
tmp := GetClass(EntryValue);
Nur wie bringe ich ihn den Konstruktor der Klasse TSchweineTransporter auszufühen und mir ein solches Objekt zu erzeugen?
wenn ich
Delphi-Quellcode:
tmp.Create;
ausführe, dann führt er nur den Konstruktor der Klasse TPersistent aus, was ja eigentlich auch logisch ist. Aber irgendwie ist doch da noch mein TSchweineTransporter mit drin, sonst würde ja
Delphi-Quellcode:
tmp.InheritsFrom(TTransporter)
nicht TRUE zurückgeben.

Oder führt da kein Weg am Factory-Pattern vorbei?

P.S.: Bitte nicht über die Logik von Transportern und Schweinetransportern nachdenken, das ist nur ein Pseudonym.

guinnes 1. Mär 2010 13:25

Re: Klasse sich selbst in eine abgeleitete konvertieren
 
Delphi-Quellcode:
Type
  TTransporterClass = Class of TTransporter;

class function TTransporter.CreateInstanz(EntryValue : TTransporterClass): TTransporter;
begin
  Result := EntryValue.Create;
end;
Ungetestet, sollte aber gehen

Patrick 1. Mär 2010 13:54

Re: Klasse sich selbst in eine abgeleitete konvertieren
 
Negativ

Hierbei würde nur der Konstruktor von TTransporter ausgeführt werden, nicht aber der von TSchweineTransporter.

"Würde", weil ich "GetClass" verwende, was mir ein "TPersistent" zurück gibt. Müsste dann auch funktionieren, tut es aber leider nicht.

(Ableitung Schaut folgendermaßen aus: TObject -> TPersistent -> TTransporter -> TSchweineTransporter)

Uwe Raabe 1. Mär 2010 14:02

Re: Klasse sich selbst in eine abgeleitete konvertieren
 
Wenn du den constructor der abgeleiteten Klasse aufrufen willst, musst du den von TTransporter virtual machen und den abgeleiteten override.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:31 Uhr.
Seite 1 von 2  1 2      

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