【问题标题】:Resolve naming conflicts caused by interface inheritance in Delphi解决Delphi中接口继承引起的命名冲突
【发布时间】:2015-04-19 09:13:00
【问题描述】:

如果我有这 3 个接口

unit Interfaces;

interface
type
  IA = interface['{86367399-1601-4FDD-89CF-362E762D948E}']
  procedure doSomething;
end;

  IB = interface['{070B9364-4A57-4E5A-BBA7-FBF1C6A48C5A}']
  procedure doSomething;
end;

  IC =interface(IB)['{DAC8021C-42CB-40EC-A001-466909044EC3}']
  procedure doSomething;
end;

implementation

end.

如何解决实现 IA 和 IC 的类中的命名冲突? 我对 IA 和 IC 没有问题,但我如何实现 IB?

type
   myClass = class(TInterfacedObject, IA, IC)
    procedure doASomething;
    procedure doBSomething;
    procedure doCSomething;
    procedure IA.doSomething = doASomething;
    //        ???            = doBSomething;
    procedure IC.doSomething = doCSomething;

  end;

【问题讨论】:

  • 扩展IB(即IC)重新声明一个相同的方法真的有意义吗?由于IC 扩展了IBprocedure doSomething; 已经可用。作为使用IC 实现的客户,您如何称呼IC 的doSomething 和IB 的doSomething
  • @CraigYoung (intf as IB).doSomething()(intf as IC).doSomething()
  • @DavidHeffernan 不,我指的不是这个,但我能理解这种困惑。 IC 有 2 个相同的 doSomethings:它自己的,一个来自它扩展的接口。那么客户如何指示要调用这两个中的哪一个呢?如果对象仅实现 IC 而不是IB,则(intf as IB) 将无效。此外,如果一个对象确实实现了 IBIC,那么它需要提供对3 个单独的doSomethings 的访问;以及客户如何区分所有 3 个?

标签: delphi inheritance interface


【解决方案1】:

根据我的comment:
IB(即IC)的扩展重新声明一个相同的方法真的有意义吗?由于IC 扩展了IBprocedure doSomething; 已经可用。作为使用IC 实现的客户,您如何称呼IC 的doSomething 和IB 的doSomething

因此,如果您执行以下操作,应该没有问题。

IC =interface(IB)['{DAC8021C-42CB-40EC-A001-466909044EC3}']
  //procedure doSomething; //Don't redeclare an existing method in an extension.
end;

type
   myClass = class(TInterfacedObject,
     //Explicitly state that you're implementing IB
     IA, IB, IC)

     procedure doASomething;
     procedure doBSomething;
     procedure doCSomething;
     procedure IA.doSomething = doASomething;
     //And you'll be able to define IB's method resolution.
     procedure IB.doSomething = doBSomething;
     procedure IC.doSomething = doCSomething;
   end;

您还可以在this question 中找到一些有用的信息和答案,因为它讨论了为什么需要明确说明类实现了哪些接口。

【讨论】:

    【解决方案2】:

    你的类没有实现IB。因此,无法为该类未实现的接口使用方法解析子句。因此,您可能会认为最简单的方法是实现该接口:

    type
      myClass = class(TInterfacedObject, IA, IB, IC)
        procedure doASomething;
        procedure doBSomething;
        procedure doCSomething;
        procedure IA.doSomething = doASomething;
        procedure IB.doSomething = doBSomething;
        procedure IC.doSomething = doCSomething;
      end;
    

    但这也无法编译。错误是:

    [dcc32 错误]:E2291 缺少接口方法 IB.doSomething 的实现

    我的结论是,您无法直接实现这些接口。我认为你可以将这个特定的圆圈平方的唯一方法是use an implements clause to delegate implementation。例如:

    type
      myClass = class(TInterfacedObject, IA, IB, IC)
      private
        FA: IA;
        FB: IB;
        FC: IC;
        property A: IA read FA implements IA;
        property B: IB read FB implements IB;
        property C: IC read FC implements IC;
      end;
    

    显然您需要初始化字段FAFBFC,但我将其留给您作为练习。

    这不是一个非常令人满意的解决方案。如果我在你的位置,我会非常努力地寻找一种从一开始就避免名称冲突的解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-18
      • 2018-09-17
      • 1970-01-01
      • 2011-01-31
      • 1970-01-01
      • 2020-12-27
      相关资源
      最近更新 更多