我需要一个类实现接口,没有引用计数.我做了以下:
IMyInterface = interface(IInterface) ['{B84904DF-9E8A-46E0-98E4-498BF03C2819}'] procedure InterfaceMethod; end; TMyClass = class(TObject,IMyInterface) protected function _AddRef: Integer;stdcall; function _Release: Integer;stdcall; function QueryInterface(const IID: TGUID; out Obj): HResult;stdcall; public procedure InterfaceMethod; end; procedure TMyClass.InterfaceMethod; begin ShowMessage('The Method'); end; function TMyClass.QueryInterface(const IID: TGUID; out Obj): HResult; begin if GetInterface(IID,Obj) then Result := 0 else Result := E_NOINTERFACE; end; function TMyClass._AddRef: Integer; begin Result := -1; end; function TMyClass._Release: Integer; begin Result := -1; end;
缺乏参考计数工作正常.但是我担心的是,我无法使用as操作器将TMyClass转换为IMyInterface:
var MyI: IMyInterface; begin MyI := TMyClass.Create as IMyInterface;
我给了
[DCC Error] E2015 Operator not applicable to this operand type
当TMyClass从TInterfacedObject派生时,该问题消失 – 即我可以执行这样的转换而不会出现编译器错误.显然,我不想使用TInterfacedObject作为基类,因为它会使我的类引用计数.为什么这样的铸造不允许,如何解决它?
解决方法
您不能像代码中那样使用的原因是您的类不会在支持的接口列表中显式列出IInterface.即使您的界面源自IInterface,除非您实际列出该界面,否则您的类不支持.
所以,这个简单的修复就是这样声明你的课程:
TMyClass = class(TObject,IInterface,IMyInterface)
您的类需要实现IInterface的原因是编译器为了实现as cast而依赖的原因.
我想提出的另一点是,一般来说,你应该避免使用接口继承.总的来说,它的用途很少.使用接口的好处之一是您不需要实现继承的单一继承约束.
但在任何情况下,所有的Delphi接口automatically inherit from IInterface
,所以在你的情况下没有指出这一点.我会声明你的界面如下:
IMyInterface = interface ['{B84904DF-9E8A-46E0-98E4-498BF03C2819}'] procedure InterfaceMethod; end;
更广泛地说,你应该尽量不要使用你的接口继承.通过采取这种方法,您将鼓励更少的耦合,并导致更大的灵活性.