我有一个主类和几个实现具有相同名称的方法的继承类,如下所示:
MainClass = class(TImage)
//main class methods...
end;
MyClass1 = class(MainClass)
procedure DoSomething;
end;
MyClass2 = class(MainClass)
procedure DoSomething;
end;
MyClass3 = class(MainClass)
procedure DoSomething;
end;
我还有一个包含指向对象实例(几个类)的指针的TList。
如果我想为每个类调用正确的DoSomething
过程,请使用以下内容吗?
if TList[i] is MyClass1 then
MyClass1(TList[i]).DoSomething
else if TList[i] is MyClass2 then
MyClass2(TList[i]).DoSomething
else if TList[i] is MyClass3 then
MyClass3(TList[i]).DoSomething
是否有一些转换方法允许我在几行代码中执行此操作?
答案 0 :(得分:10)
是的,虚拟多态::)
MainClass = class(TImage)
procedure DoSomething; virtual;
end;
MyClass1 = class(MainClass)
procedure DoSomething; override;
end;
MyClass2 = class(MainClass)
procedure DoSomething; override;
end;
MyClass3 = class(MainClass)
procedure DoSomething; override;
end;
然后只是:
if TList[i] is MainClass then
MainClass(TList[i]).DoSomething
如果您不想执行空MainClass.DoSomething
程序,也可以将其标记为virtual; abstract;
。
答案 1 :(得分:4)
虚拟继承答案最适合您所描述的类从公共基类下降的情况,但如果您的类之间没有公共基类并且您需要此行为,则可以使用接口来实现相同的结果:
IMainInterface = interface
['{0E0624C7-85F5-40AF-ADAC-73B7D79C264E}']
procedure DoSomething;
end;
MyClass = class(TInterfacedObject, IMainInterface)
procedure DoSomething;
destructor Destroy; override;
end;
MyClass2 = class(TInterfacedObject, IMainInterface)
procedure DoSomething;
end;
MyClass3 = class(TInterfacedObject, IMainInterface)
procedure DoSomething;
end;
然后使用它看起来像这样:
var
i: integer;
list: TInterfaceList;
main: IMainInterface;
begin
list := TInterfaceList.Create;
list.Add(MyClass.create);
list.Add(MyClass2.Create);
list.Add(MyClass3.Create);
for i := 0 to 2 do
if Supports(list[i], IMainInterface, main) then
main.DoSomething;
list.Free;