gpt4 book ai didi

delphi - 没有泛型的接口(interface)继承

转载 作者:行者123 更新时间:2023-12-03 15:09:13 25 4
gpt4 key购买 nike

我正在尝试实现一个接口(interface),将数据集中的记录转换为 Delphi 预泛型版本中的 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;

基本上,我有一个具体的基类,其中包含私有(private)数据集并实现 IBaseRecordCollection 和每个 RecordCollection 接口(interface)的具体类,该接口(interface)派生自实现 IBaseRecordCollection 的抽象类(已处理通过 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;

虽然这有效,但我不喜欢 supports 调用以及像这样混合我的 lRecordCollections 和 lRecARecordCollections 。我原本希望能够做这样的事情:

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;

但不幸的是,Delphi 不够聪明,没有意识到 IRecARecordCollection 的实现是在 Collection 属性 implements 调用中的基本 IBaseRecordCollection 和 TRec1RecordCollection 对象上分割的。

对于实现这一目标,还有其他更好的建议吗?

-- 编辑以给出比评论中可能的(更长)@David 答案的回复

建议的解决方案:

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 相关的方法。我还尝试将 Collection 属性从 Abstract 移动到 Rec1RecordCollection 并在 TRec1RecordCollection 中重新声明该属性,结果均相同

再深入一点,似乎可以直接继承实现 IBaseRecordCollection 的类,但 Delphi 无法使用 implements 通过属性间接实现这一点。

最佳答案

你的代码就快到了。代码中的implements指令无法编译,因为您只声明您的类实现了派生接口(interface)。就目前情况而言,您的类并未实现 Implements 指令所引用的接口(interface),即 IBaseRecordCollection。您可能认为这是从继承中推断出来的,但事实并非如此。

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

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

只需进行一点小小的更改,您的代码就可以编译。

更新

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

编译器应该接受此代码,但事实上它不接受是因为编译器错误。现代版本的 Delphi 将接受您对问题的更新中的代码。

除非升级编译器,否则您将无法实现预期的设计。

关于delphi - 没有泛型的接口(interface)继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19055565/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com