【问题标题】:Interface helpers or delegating interface parent接口助手或委托接口父级
【发布时间】:2011-02-10 08:24:22
【问题描述】:

如果我有一个由第三方实现的现有IInterface 后代,并且我想添加辅助例程,Delphi 是否提供任何简单的方法来做到这一点,而无需手动重定向每个接口方法?也就是说,给定这样的接口:

IFoo = interface
  procedure Foo1;
  procedure Foo2;
  ...
  procedure FooN;
end;

是否支持类似以下的内容?

IFooHelper = interface helper for IFoo
  procedure Bar;
end;

IFooBar = interface(IFoo)
  procedure Bar;
end;

TFooBar = class(TInterfacedObject, IFoo, IFooBar)
private
  FFoo: IFoo;
public
  procedure Bar;
  property Foo: IFoo read FFoo implements IFoo;
end;

我特别想知道如何让我始终使用单个变量引用(IFoo、IFooBar 或 TFooBar)调用 Foo1、Foo2 和 Bar,而无需在它们之间切换,也无需将所有 IFoo 的方法添加到TFooBar。

【问题讨论】:

    标签: delphi interface


    【解决方案1】:

    将你的班级改为阅读:

    TFooBar = Class(TInterfacedObject, IFoo, IFooBar)
    private
      FFoo: IFoo;
    public
      procedure Bar;
      property Foo: IFoo read FFoo implements IFoo ;
    end;
    

    您还需要一个构造函数或一些方法来创建 IFoo 的实例并将其放置在 FFoo 中。

    【讨论】:

    • “类与接口”和缺少的“读取 FFoo”是拼写错误。即使更正它们,该示例也不起作用。如果我有对 TFooBar 的引用,我不能调用“FooBar.Foo1”;它被认为是未声明的。
    • 如果你想使用 IFooBar 并暴露它们,我相信你需要在 IFooBar 中重新声明 IFoo 的过程。
    • Skamradt 是对的。 Delphi 中没有“接口助手”。不过,如果有就好了。尝试在 QC 中添加它。
    • 我在 Delphi 中找到了一个用于“接口助手”语言功能的 QC:qc.embarcadero.com/wc/qcmain.aspx?d=93289
    【解决方案2】:

    您不能通过对 TFooBar 的引用访问 IFoo 的方法,因为 TFooBar 没有实现 IFoo - 它代表 IFoo。但是无论如何,您都不应该使用 TFooBar 引用来访问接口对象,这就是首先使用接口的全部意义!

    注意:为了故意防止这种情况,我采用了将我的类上的接口方法实现为“受保护”的约定,特别是拒绝访问那些实现细节,除非通过接口本身浮出水面。

    无论您当前在何处获取对 TFooBar 的引用,请将其更改为获取 TFooBar 实现的 IFooBar 接口 你会被排序。

    【讨论】:

    • 显然我的帖子不清楚。我有一个来自第三方的“IFoo”,我无法控制。我想向它添加额外的辅助函数,就像类助手一样。 TFooBar 和 IFooHelper 是我提出的关于如何发生这种情况的语法。
    【解决方案3】:

    我不确定我是否理解您的所有顾虑,但无论如何,这是我的建议:

    IFooBar = interface(IFoo)
      procedure Bar;
    end;
    
    TFooDelegate = class(TInterfacedObject, IFoo )
    private
      FFoo: IFoo;
    public
      property Foo: IFoo read FFoo implements IFoo;
    end;
    
    TFooBar = class( TFooDelegate, IFooBar )
      procedure Bar;
    end;
    

    【讨论】:

      【解决方案4】:

      https://docwiki.embarcadero.com/RADStudio/Sydney/en/Implementing_Interfaces:_Delphi_and_C%2B%2B 关于如何在属性中使用 TAggregatedObject 和“实现”语法

      从那里引用:

      unit Unit1;
       
       interface
       
       type
       
        // Interface that exposes an 'Add' method
        IAdder = interface
        ['{D0C74612-9E4D-459A-9304-FACE27E3577D}']
          function Add(I, J: Integer): Integer;
        end;
       
        // Aggregatee that implements IAdder
        TAdder = class(TAggregatedObject, IAdder)
          function Add(I, J: Integer): Integer;
        end;
       
        // Aggregator - implements IAdder via TAdder
        TPasClass = class(TInterfacedObject, IAdder)
          FAdder: TAdder;
          function GetAdder: TAdder;
        public
          destructor Destroy; override;
          property Adder: TAdder read GetAdder write FAdder implements IAdder;
        end;
       
       function TestAdd(I, J: Integer): Integer; 
       
       implementation
       
       { TAdder }
       function TAdder.Add(I, J: Integer): Integer;
       begin
         Result := I+J;
       end;
       
       { TPasClass }
       destructor TPasClass.Destroy;
       begin
         FAdder.Free;
         inherited;
       end;
       
       function TPasClass.GetAdder: TAdder;
       begin
         if FAdder = nil then
           FAdder := TAdder.Create(Self as IInterface);
         Result := FAdder;
       end;
       
       // Adds using TClass' IAdder
       function TestAdd(I, J: Integer): Integer; 
       var
         punk: IInterface;
       begin
         punk := TPasClass.Create as IInterface;
         Result := (punk as IAdder).Add(I, J);
       end;
       
       end.
      

      如果能做到就好了:

      TSomeClassIFoo123Helper = class helper(IFoo1, IFoo2, IFoo3) for TSomeClass
        procedure Bar1;
        procedure Bar2;
        procedure Bar3;
      end;
      

      将 IFoo1、IFoo2、IFoo3 接口实现注入 TSomeClass。助手支持继承,但只能在列表中指定另一个助手类,而不是一个或多个接口

      【讨论】:

        猜你喜欢
        • 2014-08-18
        • 2021-02-20
        • 1970-01-01
        • 2012-02-11
        • 2012-07-05
        • 2012-01-31
        • 2010-10-07
        • 2020-08-22
        • 1970-01-01
        相关资源
        最近更新 更多