- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试实现一个接口(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/
我正在尝试在我的代码库中为我正在编写的游戏服务器更多地使用接口(interface),并了解高级概念以及何时应该使用接口(interface)(我认为)。在我的例子中,我使用它们将我的包相互分离,并使
我有一个名为 Widget 的接口(interface),它在我的整个项目中都在使用。但是,它也用作名为 Widget 的组件的 Prop 。 处理此问题的最佳方法是什么?我应该更改我的 Widget
有一个接口(interface)可以是多个接口(interface)之一 interface a {x:string} interface b {y:string} interface c {z:st
我遇到了一种情况,我需要调用第三方服务来获取一些信息。这些服务对于不同的客户可能会有所不同。我的界面中有一个身份验证功能,如下所示。 interface IServiceProvider { bool
在我的例子中,“RequestHandlerProxy”是一个结构,其字段为接口(interface)“IAdapter”,接口(interface)有可能被调用的方法,该方法的输入为结构“Reque
我有一个接口(interface)Interface1,它已由类A实现,并且设置了一些私有(private)变量值,并且我将类A的对象发送到下一个接受输入作为Interface2的类。那么我怎样才能将
假设我有这样的类和接口(interface)结构: interface IService {} interface IEmailService : IService { Task SendAs
有人知道我在哪里可以找到 XML-RPC 接口(interface)的定义(在 OpenERP 7 中)?我想知道创建或获取对象需要哪些参数和对象属性。每个元素的 XML 示例也将非常有帮助。 最佳答
最近,我一直在阅读有关接口(interface)是抽象的错误概念的文章。一篇这样的帖子是http://blog.ploeh.dk/2010/12/02/InterfacesAreNotAbstract
如果我有一个由第三方实现的现有 IInterface 后代,并且我想添加辅助例程,Delphi 是否提供了任何简单的方法来实现此目的,而无需手动重定向每个接口(interface)方法?也就是说,给定
我正在尝试将 Article 数组分配给我的 Mongoose 文档,但 Typescript 似乎不喜欢这样,我不知道为什么它显示此警告/错误,表明它不可分配. 我的 Mongoose 模式和接口(
我有两个接口(interface): public interface IController { void doSomething(IEntity thing); } public inte
是否可以创建一个扩展 Serializable 接口(interface)的接口(interface)? 如果是,那么扩展接口(interface)的行为是否会像 Serilizable 接口(int
我试图在两个存储之间创建一个中间层,它从存储 A 中获取数据,将其转换为相应类型的存储 B,然后存储它。由于我需要转换大约 50-100 种类型,我希望使用 map[string]func 并根据 s
我正在处理一个要求,其中我收到一个 JSON 对象,其中包含一个日期值作为字符串。我的任务是将 Date 对象存储在数据库中。 这种东西: {"start_date": "2019-05-29", "
我们的方法的目标是为我们现有的 DAO 和模型类引入接口(interface)。模型类由各种类型的资源 ID 标识,资源 ID 不仅仅是随机数,还带有语义和行为。因此,我们必须用对象而不是原始类型来表
Collection 接口(interface)有多个方法。 List 接口(interface)扩展了 Collection 接口(interface)。它声明与 Collection 接口(int
我有一个 Java 服务器应用程序,它使用 Jackson 使用反射 API 对 DTO 进行一般序列化。例如对于这个 DTO 接口(interface): package com.acme.libr
如果我在 Kotlin 中有一个接口(interface): interface KotlinInterface { val id: String } 我可以这样实现: class MyCla
我知道Java中所有访问修饰符之间的区别。然而,有人问了我一个非常有趣的问题,我很难找到答案:Java 中的 private 接口(interface)和 public 接口(interface)有什
我是一名优秀的程序员,十分优秀!