Je nach einer äußeren Bedingung muss ich eine von den abgeleiteten Klassen (TDerivedClass1, TDerivedClass2) instantiieren.
Im Moment mache ich das so:
Code: Alles auswählen
program project1;
{$mode ObjFPC}{$H+}
{$interfaces corba}
uses
SysUtils;
type
ITestInterface = interface
procedure Identify;
end;
{ TBaseClass }
TBaseClass = class(ITestInterface)
public
procedure Identify; virtual; abstract;
end;
{ TDerivedClass1 }
TDerivedClass1 = class(TBaseClass)
public
procedure Identify; override;
end;
{ TDerivedClass2 }
TDerivedClass2 = class(TBaseClass)
public
procedure Identify; override;
end;
function GetClass(s: string): TBaseClass;
begin
Result := nil;
if LeftStr(s, 1) = '1' then exit(TDerivedClass1.Create);
if LeftStr(s, 1) = '2' then exit(TDerivedClass2.Create);
end;
procedure TDerivedClass1.Identify;
begin
Writeln('Hello from class 1');
end;
{ TDerivedClass2 }
procedure TDerivedClass2.Identify;
begin
Writeln('Hello from class 2');
end;
var
MyClass: TBaseClass;
s: string;
begin
MyClass := nil;
repeat
Write('Klasse: ');
Readln(s);
if s <> '' then
begin
if Assigned(MyClass) then
FreeAndNil(MyClass);
MyClass := GetClass(s);
if assigned(MyClass) then
MyClass.identify
else
writeln('Unknown class: ' + s);
end;
until s = '';
if Assigned(MyClass) then
FreeAndNil(MyClass);
end.
(2) (Nur zur Kontrolle ob ich nicht einen OOP Denkfehler habe) An sich tut TBaseClass selber nichts, sondern definiert nur abstrakte Methoden, welche von den abgeleiteten Klassen dann zu erfüllen sind. Daher muss ich alle im Interface enthaltenen Member in jeder Klasse nochmal deklarieren und ggf implementieren. Interfaces sind also nichts anderes als eine Schablone, eine Merkhilfe, damit ich mich selber zwinge, alle betroffenen Klassen mit einer bestimmten Methode auszustatten. Daher habe ich TBaseClass mit dem Interface ITestInterface verbunden. Hätte ich GetClass auch irgendwie so schreiben können, dass ein Interface zurückkommt? Ich meine: nein, kann man so nicht lösen. Instantiieren kann man nur Klassen, wenn diese dann das entsprechende Interface implementieren kann man dieses gerne benützen über einen Typecast wie i := TTestInterface(myClass) und danach alles aufrufen was Teil von ITestInterface war (z.B. writeln(i.Identify)), aber instantiiert werden immer die Klassen.
Armin.