Delphi:如何从接口(interface)类型变量访问对象的基类方法

标签 delphi interface

...或相反亦然。假设我无法控制两个类,它们都继承自同一个基类:

TDataSet1 = class(TDataSet)
...
end;

TDataSet2 = class(TDataSet)
...
end;

我有一个这样的接口(interface)声明:

IMyDataSet = interface
  procedure MyProc;
end;

然后我有两个类继承了前面的类并实现了我的接口(interface):

TMyDataSet1 = class(TDataSet1, IMyDataSet)
  procedure MyProc;
end;

TMyDataSet2 = class(TDataSet2, IMyDataSet)
  procedure MyProc;
end;

现在我的问题是:我有一堆过程和函数,它们必须接受一个对象作为参数,该对象可以是我的两个类的实例。
我不需要访问特定于我的两个类或祖先类的属性或方法,只需要访问基类 TDataSet 中的属性或方法。 在接口(interface)IMyDataSet中声明的那些.

如果我声明这样的程序:

procedure Foo(ADataSet: TDataSet);

我只能从 TDataSet 调用方法类(class)。

相反,如果我以这种方式声明该过程:

procedure Foo(ADataSet: IMyDataSet);

我只能看到属于该接口(interface)的方法。

有没有办法让我看到两个TDataSetIMyDataSet方法关于我传递给程序的引用?

最佳答案

您可以将参数声明为接口(interface),然后将其类型转换为方法内的对象引用。 (这种类型转换适用于 Delphi 2010 及更高版本)

procedure Foo(ADataSet: IMyDataSet);
var
  LDataSet: TDataSet;
begin
  LDataSet := TDataSet(ADataSet);
  ... 
end;

注意:如果 IMyDataSet接口(interface)未在 TDataSet 上实现类型转换上面的类将失败而不会引发异常并返回 nil .

您也可以使用as运算符进行类型转换,但在这种情况下,失败会引发异常。
LDataSet := ADataSet as TDataSet;

另一种选择是将参数作为对象实例传递,然后从对象中检索接口(interface)。在这种情况下,您的界面必须具有 GUID。
IMyDataSet = interface
  ['{XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}'] // replace with actual GUID
  procedure MyProc;
end;

procedure Foo(ADataSet: TDataSet);
var
  LDataSet: IMyDataSet;
begin
  if Supports(ADataSet, IMyDataSet, LDataSet) then
    begin
      ... 
    end;
end;

关于Delphi:如何从接口(interface)类型变量访问对象的基类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57181506/

相关文章:

vba - 在 VBA 中实现接口(interface)时,为什么参数被重命名为 RHS?

.net - 如何对 IList<T> 执行二分查找?

api - 接口(interface)控制文件例子?

c# - 在 .NET 中派生 COM 接口(interface)

forms - 如何将一个 Delphi 窗体移到另一个窗体前面?

Delphi for 循环和 StringList 错误

string - Delphi XE2 AnsiFormat() 和 ANSI 字符串常量

c# - 接口(interface)变量是否具有值类型或引用类型语义?

delphi - 如何获取Firemonkey XE3中的屏幕分辨率?

delphi - 十六进制到十进制转换器 (ESN Algo)