简体   繁体   English

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

[英]Delphi: how to access an object's base class methods from an interface type variable

...or vice versa. ...或相反亦然。 Let's suppose two classes on which I have no control, both inherit from the same base class: 假设有两个我无法控制的类,它们都继承自同一基类:

TDataSet1 = class(TDataSet)
...
end;

TDataSet2 = class(TDataSet)
...
end;

I have an interface declaration like this: 我有一个这样的接口声明:

IMyDataSet = interface
  procedure MyProc;
end;

Then I have two classes that inherit from the previous ones and that implement my interface: 然后,我有两个继承自先前类的类,它们实现了我的接口:

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

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

Now my problem is: i have a bunch of procedures and functions which must accept as parameter an object which can be an instance of both my classes. 现在我的问题是:我有一堆程序和函数,它们必须接受一个对象作为参数,该对象可以是我两个类的实例。 I don't need to access properties or methods specific to my two classes or to the ancestor ones, only those from the base class TDataSet and those declared in the interface IMyDataSet . 我并不需要访问特定的属性或方法,以我的两个类或祖先的,只有那些从基类TDataSet 那些在接口中声明IMyDataSet

If I declare a procedure like this: 如果我声明这样的过程:

procedure Foo(ADataSet: TDataSet);

I can only call methods from TDataSet class. 我只能从TDataSet类调用方法。

If instead I declare the procedure in this way: 相反,如果我以这种方式声明过程:

procedure Foo(ADataSet: IMyDataSet);

I can see only methods that belong to that interface. 我只能看到属于该接口的方法。

Is there a way so that I can see both TDataSet and IMyDataSet methods on the reference I pass to the procedure? 有没有一种方法可以让我在传递给该过程的引用上同时看到TDataSetIMyDataSet方法

You can declare parameter as interface and then typecast it to object reference inside method. 您可以将参数声明为接口,然后将其类型转换为方法内部的对象引用。 (This kind of typecasting works in Delphi 2010 and newer) (这种类型转换适用于Delphi 2010及更高版本)

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

Note: If IMyDataSet interface is not implemented on TDataSet class above typecast will fail without raising exception and return nil . 注意:如果未在TDataSet类上实现IMyDataSet接口,则上述类型转换将在不引发异常的情况下失败并返回nil

You can also use as operator to typecast, but in that case failure raises exception. 您还可以使用as运算符进行类型转换,但是在这种情况下,失败会引发异常。

LDataSet := ADataSet as TDataSet;

Another option is to pass parameter as object instance and then retrieve interface from object. 另一种选择是将参数作为对象实例传递,然后从对象检索接口。 In that case your interface must have GUID. 在这种情况下,您的界面必须具有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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM