Delphi对象转换

时间:2012-01-29 09:19:03

标签: delphi casting

我有一个主类和几个实现具有相同名称的方法的继承类,如下所示:

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

是否有一些转换方法允许我在几行代码中执行此操作?

2 个答案:

答案 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;