【发布时间】:2023-03-29 07:25:02
【问题描述】:
我知道这是旧的,我使用的是 Delphi 5。不确定在更高版本的 Delphi 中是否相同。
我发现如果一个对象将自己的接口实现委托给另一个对象,原来的对象不能直接调用接口方法,我期待委托接口实现应该是什么。
这是我的问题
IFoo = interface
procedure InterfaceMethod;
end;
TBar = class(TComponent, IFoo)
FFoo: IFoo;
procedure ObjectMethod;
property Foo: IFoo read FFoo implements IFoo;
end;
TBar.Method2
begin
InterfaceMethod; // this will give compile error, Method1 not declared!
(Self as IFoo).InterfaceMethod; // compile error, saying operation not supported.
FFoo.InterfaceMethod; // this work, but meaningless, since this can be any object, why the need of interface!
end;
如果我在 TBar 类之外执行此操作,则类似。说
Bar := TBar.Create;
Bar.InterfaceMethod; // compile error
(Bar as IFoo).InterfaceMethod; // compile error
Bar.Foo.Method1; // this work, but...
谁能解释为什么会这样或者我的理解不正确。或者可能在 D5 之后这将是正确的?
以下是示例代码
unit iwSqlDbEngine;
//
// Database resource and helper funcions.
//
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Db, ScktComp, ExtCtrls;
type
ISqlMaker = interface
['{5A671E7B-957B-4A52-BB5E-87EEA8E5687B}']
procedure SetSqlStatement(const value: string);
function GetSqlStatement: string;
// Insert and update
function Insert(table: string): ISqlMaker;
function Update(table: string): ISqlMaker;
function AddField(fieldname: string; value: variant; isExpr: Boolean = False): ISqlMaker; overload;
function AddField(field: TField): ISqlMaker; overload;
// Delete
function Delete(table: string): ISqlMaker;
// Select
function Select(table: string; columns: array of string): ISqlMaker;
function Join(table: string; columns, matches: array of string): ISqlMaker;
function LeftJoin(table: string; columns, matches: array of string): ISqlMaker;
// Other clauses
function Where(aExpr: string): ISqlMaker;
function GroupBy(columns: array of string): ISqlMaker;
function OrderBy(columns: array of string): ISqlMaker;
function Having(vExprs: array of string): ISqlMaker;
property SqlStatement: string read GetSqlStatement write SetSqlStatement;
end;
TSampleDbEngine = class(TComponent, ISqlMaker)
private
FSqlMaker: ISqlMaker;
public
procedure Execute;
property SqlMaker: ISqlMaker read FSqlMaker write FSqlMaker implements ISqlMaker;
end;
implementation
procedure TSampleDbEngine.Execute;
begin
(Self as ISqlMaker).GetSqlStatement;
end;
end.
与上述相同的编译错误。
【问题讨论】:
-
你能不能提供一个minimal reproducible example来代替这个伪代码
-
以上是可以编译的最少代码。抱歉,Method1 指的是 InterfaceMethod,Method2 是 ObejctMethod。我在初稿中使用 Method1 和 Method2,认为名称更改更清晰。 TBar.Method2 应该是过程 TBar.ObjectMethod;
-
不,不是。我们不知道变量的类型,并且大部分语法都是由组成的。请加倍努力。如果问题得到解决,这个问题将得到一个很好的答案。
-
您的示例代码使情况变得更糟。清楚地表明原始代码是假的。请点击我第一条评论中的链接并仔细阅读。一个好的minimal reproducible example 会产生巨大的影响。