解决Delphi中由接口继承引起的命名冲突

时间:2015-02-18 11:24:26

标签: delphi inheritance interface

如果我有这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;

2 个答案:

答案 0 :(得分:1)

您的课程未实施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 Error]: E2291 Missing implementation of interface method 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,但我将其作为练习留给您。

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

答案 1 :(得分:1)

根据我的comment
扩展IB(即IC)以重新声明相同的方法是否真的有意义?由于IC延伸IBprocedure doSomething;已经可用。作为使用IC实施的客户,您如何以不同于IB doSomething的方式调用IC的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中找到一些有用的信息,并且答案很有用,因为它讨论了为什么需要明确说明类实现哪些接口。