Delphi中的接口多态性

3
我有两个接口,其中一个派生自另一个:
type
  ISomeInterface = interface
    ['{5A46CC3C-353A-495A-BA89-48646C4E5A75}']
  end;

  ISomeInterfaceChild = interface(ISomeInterface)
    ['{F64B7E32-B182-4C70-A5B5-72BAA92AAADE}']
  end;

现在我有一个过程,其中参数是ISomeInterface,如下:

procedure DoSomething(SomeInterface: ISomeInterface);

我想检查SomeInterface是否是ISomeInterfaceChild。在Delphi 7中,界面不支持Is运算符,并且我也不能在这里使用Supports。我该怎么办?

2个回答

5

你确实可以使用Supports。 你只需要:

Supports(SomeInterface, ISomeInterfaceChild)

这个程序说明了:
program SupportsDemo;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  ISomeInterface = interface
    ['{5A46CC3C-353A-495A-BA89-48646C4E5A75}']
  end;

  ISomeInterfaceChild = interface(ISomeInterface)
    ['{F64B7E32-B182-4C70-A5B5-72BAA92AAADE}']
  end;

procedure Test(Intf: ISomeInterface);
begin
  Writeln(BoolToStr(Supports(Intf, ISomeInterfaceChild), True));
end;

type
  TSomeInterfaceImpl = class(TInterfacedObject, ISomeInterface);
  TSomeInterfaceChildImpl = class(TInterfacedObject, ISomeInterface, ISomeInterfaceChild);

begin
  Test(TSomeInterfaceImpl.Create);
  Test(TSomeInterfaceChildImpl.Create);
  Readln;
end.

输出

假
真

4
你为什么说你不能使用Supports函数?它似乎是解决方案,它有一个重载版本,第一个参数采用IInterface
procedure DoSomething(SomeInterface: ISomeInterface);
var tmp: ISomeInterfaceChild;
begin
  if(Supports(SomeInterface, ISomeInterfaceChild, tmp))then begin
     // argument is ISomeInterfaceChild
  end;

应该做你想要的。

如果您只需要检查接口是否支持 ISomeInterfaceChild,那么您正在使用错误的重载。您应该使用我在答案中演示的两个参数的重载。 - David Heffernan
我假设如果你需要检查参数ISomeInterfaceChild,那么你也需要将其作为ISomeInterfaceChild来使用。否则这个检查就没有意义,它不应该有影响,因此检查它可能会暴露出设计问题。 - ain
1
@ain:不一定。有时候接口被用来宣传包含对象的特性,而不是为它们暴露新的函数。在这种情况下,仅仅检查支持接口的存在就足够了。 - Remy Lebeau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接