Ich habe ein betriebswirtschaftliches Problem zu lösen, für das es verschiedene Lösungsansätze gibt. Also habe ich eine Basisklasse programmiert, die quasi protected deklarierte Tools enthält und eine abstrakte, virtuelle Methode solve. In Java ist so was ein Interface.
Nun will ich folgendes tun: Ich bilde Subklassen dieser Klasse, in denen ich verschiedene Lösungsmethoden implementiere (Brute Force, Branch&Bound, usw.).
Nun aber mein Problem: Im Hauptprogramm möchte ich eine Methode plugin(name, Klasse); programmieren, die folgendes tut:
- den Namen in eine Dropdownliste einfügen, wo der Benutzer das
Verfahren auswählen kann
- die Klasse (Wichtig: Die Klasse! Keine Instanz!) in eine Liste
einfügen
Da liegt nun mein Problem. Ich möchte ja nicht schon beim Programmstart tausend Instanzen bilden (die ja dann alle schon die Daten halten) und nur die Instanzen per case-Auswahl aufrufen, das wäre ja etwas billig und unflexibel. Außerdem möchte ich so was mal probieren, weil das Bankingprogramm u.U. dann auch verschiedene Module als Plugins unterstützen soll.
Vielmehr möchte ich zur Laufzeit anhand des Indizes der Dropdownlist die richtige Klasse instantiieren und ihre solve-Methode aufrufen. Dummerweise scheint das nicht so richtig zu gehen.
Wenn ich so was in der Art tue:
Klasse A
Klasse B (abgeleitet von A)
Klasse C (abgeleitet von A)
Quelltext
1: 2: 3: 4: 5: 6:
| Hauptprogramm bei Startbuttonklick: Var x :A; Begin x:=B.create; (B ist aus der Auswahlliste entnommen, könnte auch C sein) x.solve; End; |
Dann ruft er die Methode solve aus der Klasse A auf und beschwert sich mit "abstrakter Fehler".
Das Problem ist, dass ich beim Compilieren noch nicht weiss, welche Subklasse ich verwenden werde.
Momentan ist es etwa so implementiert:
ta -> Basisklasse
tb,tc -> Subklassen von ta, die die abstrakte, virtuelle Methode solve implementieren
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TForm1.Button1Click(Sender: TObject); var b :tb; c :tc; begin case index of 0: begin b:= tb.Create; b.solve; end; 1: begin c:= tc.Create; c.solve; end; end; end; |
Das muss aber irgendwie eleganter gehen. Ich will wie gesagt zur Laufzeit bestimmen, von welcher Subklasse ich eine Instanz bilde, mit der ich dann weiterarbeite.
Die jetzige Lösung ist viel zu sehr ein Hack und wirklich unschön, vor allem wenn man noch mehr Code als bloss das solve hat.
Mein Versuch geht leider auch nicht:
Quelltext
1: 2: 3: 4: 5: 6:
| var a :^TClass; begin a:=TSubKlasse; a^:=TSubKlasse.create; a.solve; end; |
Ich versuche im Prinzip, eine Referenz auf eine Klasse anzulegen, der ich dann eine Klasse als Typ zuweise und davon möchte ich dann eine Instanz erzeugen. Wahrscheinlich kann Delphi sowas gar nicht, ist eher so eine Art dynamische Kompilierung a la ObjectiveC. Wenn ich mich recht erinnere, habe ich das aber auch in Java schon mal gemacht.
Kann mir da jemand weiterhelfen? Danke!!!
Code-Tags hinzugefügt. Tino