Resolve naming conflicts caused by interface inheritance in Delphi

孤者浪人 提交于 2020-01-17 03:43:17

问题


If i have these 3 interfaces

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.

How do i resolve naming conficts in a class that implements IA and IC? I have no problem with IA and IC but how do i implement IB?

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

  end;

回答1:


Your class doesn't implement IB. So there's no way to use a method resolution clause for an interface that is not implemented by that class. So, you might imagine that the easy way out is to implement that interface:

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;

But this fails to compile also. The error is:

[dcc32 Error]: E2291 Missing implementation of interface method IB.doSomething

I conclude that there is no way for you to implement these interfaces directly. I think that the only way you could square this particular circle would be to use an implements clause to delegate implementation. For instance:

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;

Obviously you'd need to initialise the fields FA, FB and FC, but I leave that as an exercise for you.

This isn't a very satisfactory solution. If I were in your place, I'd be looking very hard for a solution that avoided the name clashes in the first place.




回答2:


As per my comment:
Does it really make sense for an extension of IB (namely IC) to redeclare an identical method? Since IC extends IB, procedure doSomething; is already available. As a client using an implementation of IC, how would you call IC's doSomething differently from IB's doSomething?

So if you do the following, you should have no trouble.

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;

You may also find some of the information in this question and answers useful, as it discusses why you need to explicitly state which interfaces a class implements.



来源:https://stackoverflow.com/questions/28582426/resolve-naming-conflicts-caused-by-interface-inheritance-in-delphi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!