没有泛型的接口继承

时间:2013-09-27 16:17:15

标签: delphi inheritance interface delphi-2006

我正在尝试实现一个接口,将数据集中的记录转换为Delphi的pre-generics版本中的Delphi记录。我现在不喜欢这个界面,因为它总是需要调用支持,如果可能的话我想避免使用它,并且想知道是否有更好的方法可以让我失去它。

到目前为止,我已定义导航界面和数据检索界面:

IBaseRecordCollection = interface
  procedure First;
  procedure Next;
  function BOF: boolean;
  ... // other dataset nav stuff
end;

IRecARecordCollection = interface
  function GetRec: TRecA;
end;

IRecBRecordCollection = interface
  function GetRec: TRecB;
end;

基本上我有一个包含私有数据集的具体基类,并为每个RecordCollection接口实现IBaseRecordCollection和具体类,该接口派生自实现IBaseRecordCollection的抽象类(由{{1}处理} property)与记录检索例程的实现:

implements

现在,为了使用这个,我被迫拥有一个返回TAbstractTypedRecordCollection = class(TInterfacedObject, IBaseRecordCollection) private FCollection: IBaseRecordCollection; protected property Collection: IBaseRecordCollection read FCollection implements IBaseRecordCollection; public constructor Create(aRecordCollection: IBaseRecordCollection); end; TRec1RecordCollection = class(TAbstractTypedRecordCollection, IRecARecordCollection); public function GetRec: TRecA; end; 的构建器然后与IRecARecordCollection混乱,我并不热衷于它,因为它总是在这里使用方式。

Supports

虽然这很有效,但我并不热衷于procedure GetMyRecASet; var lRecARecordCollection: IRecARecordCollection; lRecordCollection: IBaseRecordCollection; begin lRecARecordCollection := BuildRecACollection; if not supports(lRecARecordCollection, IBaseRecordCollection, lRecordCollection) then raise exception.create(); while not lRecordCollection.EOF do begin lRecARecordCollection.GetRec.DoStuff; lRecordCollection.Next; end; end; 调用并混合我的lRecordCollections和我的lRecARecordCollections。我原本希望能够做到这样的事情:

supports

但遗憾的是Delphi并不聪明,没有意识到IRecARecordCollection的实现是在Collection属性IBaseRecordCollection = interface // DBNav stuff end; IRecARecordCollection = interface (IBaseRecordCollection) function GetRec: TRecA; end; TRec1RecordCollection = class(TInterfacedObject, IRecARecordCollection) private FCollection: IBaseRecordCollection; protected property Collection: IBaseRecordCollection read FCollection implements IBaseRecordCollection; public function GetRec: TRecA; end; 调用和TRec1RecordCollection对象的基础IBaseRecordCollection上分开的。

是否还有其他建议可以采用更简洁的方法来实现这一目标?

- 编辑以回复@David的答案而不是评论中可能的答案

建议的解决方案:

implements

没有编译。抱怨IBaseRecordCollection = interface ['{C910BD0A-26F4-4682-BC82-605C4C8F9173}'] function GetRecNo: integer; function GetRecCount: integer; function GetFieldList: TFieldList; function EOF: boolean; function BOF: boolean; ... end; IRec1RecordCollection = interface (IBaseRecordCollection) ['{E12F9F6D-6D57-4C7D-AB87-8DD50D35DCA2}'] function GetRec: TRec1; property Rec: TRec1 read GetRec; end; TAbstractTypedRecordCollection = class(TInterfacedObject, IBaseRecordCollection) private FCollection: IBaseRecordCollection; protected property Collection: IBaseRecordCollection read FCollection implements IBaseRecordCollection; public constructor Create(aRecordCollection: IBaseRecordCollection); end; TRec1RecordCollection = class(TAbstractTypedRecordCollection, IRec1RecordCollection, IBaseRecordCollection) private function GetRec: TRec1; public property Rec: TRec1 read GetRec; end; 无法找到与TRec1RecordCollection相关的方法。我还尝试将IBaseRecordCollection属性从Abstract移到Collection并在Rec1RecordCollection中重新声明属性,但结果相同

看起来更深层似乎实现TRec1RecordCollection的类的直接继承可行,但Delphi无法使用IBaseRecordCollection通过属性间接处理它。

1 个答案:

答案 0 :(得分:7)

你的代码几乎就在那里。代码中的implements指令无法编译,因为您只声明了您的类实现了派生接口。就目前而言,您的类不实现implements指令引用的接口,即IBaseRecordCollection。您可能认为这将从继承推断,但事实并非如此。

要解决您的问题,您只需要声明TRec1RecordCollection实现两个接口:

type
  TRec1RecordCollection = class(TInterfacedObject, IBaseRecordCollection, 
    IRecARecordCollection)
  ....
  end;

只做一个小改动,你的代码就会编译。

<强>更新

您对问题的修改会稍微改变一下。鉴于原始问题中的代码,我的答案中的代码确实可以编译。但是,将任何方法添加到IBaseRecordCollection中,编译将不接受它。

编译器应该接受这个代码,而不是因为编译器错误。现代版本的Delphi将接受您对问题的更新中的代码。

除非您升级编译器,否则将无法使您的设计正常工作。