都来谈谈Delphi中的接口 请大家来谈谈自己对Delphi接口的理解,最好给出点示例,用理论与案例相结合的方式来阐述! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 推荐看看《Delphi COM深入编程》我这有PDF和光盘代码,例子一大堆。要的留个邮箱吧。 delphi接口个人感觉与COM结合得太紧了一点.并且接口不像类有类指针(不是对象指针),因此操作起来也有诸多不便 例如:a: IAnInterface; 你无法使用这样的语句: if a is IInterface then .... [email protected] 谢谢啊。要是能买到这本书那最好了 接口的使用和COM没有必然关系。接口虽然不支持is操作,但可以用Supports函数判断是否支持某个接口 麻烦5楼的兄弟发一份给我[email protected] 呵呵,结论可不能随便下哦.先说说Supports函数,此函数实际上是调用QueryInterface,而QueryInterface需要GUID那么对于没有插入GUID的接口,使用Supports是无法作正确的判断的.但是,作为一个接口类型标识,不应该由GUID唯一确立.这样就完全依赖于GUID的二进制格式.再来说说接口表的存储问题.通过对象我们可以获取类的描叙表,而接口信息存储在类表中的一个以TInterfaceEntry 为成员的接口表中结构如下 TInterfaceEntry = packed record IID: TGUID; VTable: Pointer; IOffset: Integer; {$IF defined(CPUX64)} _Filler: LongWord; {$IFEND} ImplGetter: NativeUInt; end;QueryInterface就是通过这个结构来查找对应的接口,可如果接口定义没有指定时,IID这里就是全0.这也就是QueryInterface不起作用的原因了.那么这里也就引申了一个不是问题的问题. 如果想定义一个COM接口,其GUID是全0,那么Delphi中,这种接口无法工作,与之相反的是使用VC产生一个GUID全0的接口,一样可以工作.原因是,VC中的QueryInterface全由程序员自己实现,不影响类表.甚至GUID都可以不存储.当然,有人会说产生一个全0的GUID是不合理的,没有这种需求.但是,我还真的是碰到过这种需求. 发到[email protected],[email protected]待会发到CSDN上,看来很多兄弟有需要。正在上传CSDN,待会给链接,需要的朋友直接去下载。 刚上传的东西,需要的朋友自取吧,1分一套,PDF带源码。用Delphi语言讲解com的书很少,个人觉得这本讲解比较清楚,关键还有源码可以参考。一起向作者致敬吧。http://download.csdn.net/detail/lzg827/4083738 我的意思是不能看到接口就想到COM,或者认为只有COM才会用到接口。Delphi的接口起初可能因为COM才引入的,但是它的使用就不一定和COM有关了,所以没有和COM结合得太紧影响使用的问题。所以我说接口的使用与COM没有必然联系 [email protected]多谢了 要调用dll中的类是非常困难的,但,调用dll的接口,却可能轻松实现,而且只需要标准的接口,无须GUID 大家在用delphi做项目时用接口比较少,其实用好接口,真的会很强大。特别是在业务封装方面。 麻烦5楼的兄弟也发一份给我[email protected] 真的吗?请大家也说说Delphi接口的实用情况,最常用在哪些方面,越详细越好,最常用的地方,以及怎样用,请大家畅所欲言. 都什么年代了,还学Delphi接口!弄个抽象类代替得了! 接口是许多面向对象语言都提供的,能够实现控制反转(用接口来控制实现它的类,实现接口的类必须实现它的所有的成员)。接口是服务契约,但是没有内容。有点像成员全部是抽象方法的抽象类。接口没有行为实现,而抽象类可以有行为的过程代码,可以在继承体系下调用本类的方法,可以调用抽象方法(哪怕方法体是空的,但是子类即将覆写(override))但是在Delphi等单根继承的语言中,把接口做成抽象类会受到单根限制,而多个接口则可以被同一类实现,这点和C#、Java等都一样。李维的Inside VCL和罗小平的Delphi精要都有相关的介绍。Delphi 7和之前版本的接口和COM有着许多联系,详见Inside VCL和ERIC HARMON的Delphi深入COM编程下面是Delphi精要中的一个例子type IShowString = interface(IUnknown) procedure ShowString(S: String); end; TIObject = class(TObject, IShowString) procedure ShowString(S: String); end;===========================================================================type IShowString = interface(IUnknown) procedure ShowString(S: String); end; TComponent1 = class(TComponent, IShowString) protected procedure ShowString(S: String); virtual; end; TComponent2 = class(TComponent1) protected procedure ShowString(S: String); override; end;===========================================================================var IShowStr: IShowString;begin//类和它们实现的接口是兼容的 IShowStr := TComponent2.Create(nil); IShowStr.ShowString('dd');//接口引用计数方法会最终销毁接口所属的对象,所以我们不需要显式销毁对象。我们下面会详细讲述这个问题。end; [email protected] 谢谢! 大爱啊 谢谢啦 [email protected] 给点代码吧:unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;type TForm1 = class(TForm) btn1: TButton; btn2: TButton; btn3: TButton; btn4: TButton; procedure btn4Click(Sender: TObject); procedure btn1Click(Sender: TObject); procedure btn2Click(Sender: TObject); procedure btn3Click(Sender: TObject); private { Private declarations } public { Public declarations } end; IMyinterface1 = interface function Func1: Integer; function Func2: Integer; end; IMyInterface2 = interface procedure Proc1; procedure Proc2; end; TMyClass1 = class(TInterfacedObject, IMyinterface1, IMyInterface2) public procedure Proc1; procedure proc2; function Func1: Integer; function Func2: Integer; end;var Form1: TForm1;implementation{$R *.dfm}{1、接口命名约定 I起头, 就像类从T打头一样2、接口都是从Interface继承而来,若是从根接口继承可省略3、接口成员只能是方法、属性、没有字段4、接口成员都是公开的,不需要private、protected、public、published等任何限制5、因为接口只声明、无实现,也用不到继承与覆盖相关的修饰6、一个接口可以从另一个接口继承,但不能从多个接口继承7、一个类可以实现多个接口:TMyClass = Class(父类,接口1,接口2,接口3,..) end;8、不论实现接口的类有多么丰富,接口只拥有自己声明的成员9、实现接口的类一般继承于TinterfacedObject,直接从TObject继承会增加一些麻烦而重复的工作10、接口在用完后会自己释放,并透视释放拥有它的类,这很方便,但同时带来很多问题}procedure TForm1.btn1Click(Sender: TObject);Var c : TMyClass1;begin c := TMyClass1.Create; c.Func1; c.Func2; c.Proc1; c.proc2; c.Free; end;procedure TForm1.btn2Click(Sender: TObject);var i1 : IMyinterface1;begin i1 := TMyClass1.Create; i1.Func1; i1.Func2;end;procedure TForm1.btn3Click(Sender: TObject);var i2 : IMyInterface2;begin i2 := Tmyclass1.Create; i2.Proc1; i2.Proc2;end;procedure TForm1.btn4Click(Sender: TObject);Var c: TMyClass1; i1: IMyinterface1; i2: IMyInterface2;begin C := TMyClass1.Create; i1 := c; i1.Func1; i1.Func2; i2 := c; i2.Proc1; i2.Proc2;end;{ TMyClass1 }function TMyClass1.Func1: Integer;begin ShowMessage('imyinterface1.func1'); Result := 0;end;function TMyClass1.Func2: Integer;begin ShowMessage('imyiterface1.func2'); Result := 0;end;procedure TMyClass1.Proc1;begin ShowMessage('imyiterface2.proc1');end;procedure TMyClass1.proc2;begin ShowMessage('imyiterface2.proc2');end;end.unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;type TForm1 = class(TForm) btn1: TButton; btn2: TButton; btn3: TButton; btn4: TButton; procedure btn1Click(Sender: TObject); procedure btn2Click(Sender: TObject); procedure btn3Click(Sender: TObject); procedure btn4Click(Sender: TObject); private { Private declarations } public { Public declarations } end; IMyinterface = interface procedure proc; end; TMyClass = class(TInterfacedObject, IMyinterface) public constructor create; destructor Destroy; override; procedure Proc; end;var Form1: TForm1;implementation{$R *.dfm}{ TMyClass }constructor TMyClass.create;begin inherited; ShowMessage('Tmyclass.create');end;destructor TMyClass.Destroy;begin ShowMessage('Tmyclass.destroy'); inherited;end;procedure TMyClass.Proc;begin ShowMessage('IMyInterface.Proc');end;procedure TForm1.btn1Click(Sender: TObject);Var c : TMyClass;begin c := TMyClass.create; c.Proc; c.Free; ShowMessage('*************');end;procedure TForm1.btn2Click(Sender: TObject);Var i:IMyinterface;begin i := TMyClass.create; i.proc; ShowMessage('*************');end;procedure TForm1.btn3Click(Sender: TObject);Var c : TMyClass; i : IMyinterface;begin c := TMyClass.create; i := c; // i := Imyinterface(c); 也可以这样转换 // i := c as Imyinterface;{暂时不能使用as,接口拥有Guid后才可以使用as转换} i.proc; ShowMessage('***************');end;procedure TForm1.btn4Click(Sender: TObject);Var i:IMyinterface;begin i := TMyClass.create; i.proc; i := nil; //可以这样主动释放接口,同时拥有它的类也会释放 showMessage('************');end;end.都是以前自己练习时写的,接口封装还是非常不错,用dll文件写供调用的接口,分割也不错 有劳兄弟发个到 [email protected] 多谢了。 具体指delphi跟什么的接口呢?ocx?dll?还是脚本? 十分感谢楼上共享资料,关注Delphi 我也有需要[email protected]谢谢! 最简单的接口就是一些所谓的DLL,方便使用及调用 接口,我们也可以简单的理解成一些所谓的DLL方便我们使用并调用即可 在DELPHI开发过程中,我们比较少的涉及到OO,虽然天天都在里面编程。DELPHI中接口和COM编程时紧密相连的。接口的作用是很大的,能够做到部分框架不动,只增加具体的实现。我这里有个简单的例子。我发现要把具体代码贴上来还比较麻烦。 来迟了……我也要书啊, 发我一本吧, 谢谢了, [email protected] 来迟了……我也要书啊, 发我一本吧, 谢谢了, [email protected] 也来一本 Express的问题 问个问题,烦了一早上了,大虾们帮我看看!! 请教关于处理"你们+我们+他"这种类型的字符串的函数! delphi和pb在开发数据库方面有多少差距? 再开新帖还问关于时间查询的问题,急,还是在线等!!! SQL语句的多表查询 TAccessApplication 的使用??? 怎么判断键盘上下左右按键 50分相送求windows浏览器工具栏图标放在那个DLL中(不是SHELL32。DLL) 怎样响应DBGRID中进出CELL的焦点 ftp自动上传 TO:ly_liuyang(Liu Yang) 快来拿分!第二份100分!
我这有PDF和光盘代码,例子一大堆。
要的留个邮箱吧。
例如:a: IAnInterface;
你无法使用这样的语句: if a is IInterface then ....
谢谢啊。要是能买到这本书那最好了
呵呵,结论可不能随便下哦.先说说Supports函数,此函数实际上是调用QueryInterface,而QueryInterface需要GUID
那么对于没有插入GUID的接口,使用Supports是无法作正确的判断的.
但是,作为一个接口类型标识,不应该由GUID唯一确立.这样就完全依赖于GUID的二进制格式.再来说说接口表的存储问题.通过对象我们可以获取类的描叙表,
而接口信息存储在类表中的一个以TInterfaceEntry 为成员的接口表中
结构如下
TInterfaceEntry = packed record
IID: TGUID;
VTable: Pointer;
IOffset: Integer;
{$IF defined(CPUX64)}
_Filler: LongWord;
{$IFEND}
ImplGetter: NativeUInt;
end;
QueryInterface就是通过这个结构来查找对应的接口,可如果接口定义没有指定时,IID这里就是全0.
这也就是QueryInterface不起作用的原因了.那么这里也就引申了一个不是问题的问题. 如果想定义一个COM接口,其GUID是全0,那么Delphi中,这种
接口无法工作,与之相反的是使用VC产生一个GUID全0的接口,一样可以工作.原因是,VC中的QueryInterface
全由程序员自己实现,不影响类表.甚至GUID都可以不存储.当然,有人会说产生一个全0的GUID是不合理的,没有这种需求.但是,我还真的是碰到过这种需求.
待会发到CSDN上,看来很多兄弟有需要。
正在上传CSDN,待会给链接,需要的朋友直接去下载。
用Delphi语言讲解com的书很少,个人觉得这本讲解比较清楚,关键还有源码可以参考。一起向作者致敬吧。
http://download.csdn.net/detail/lzg827/4083738
[email protected]
多谢了
[email protected]
弄个抽象类代替得了!
接口是服务契约,但是没有内容。有点像成员全部是抽象方法的抽象类。
接口没有行为实现,而抽象类可以有行为的过程代码,可以在继承体系下调用本类的方法,可以调用抽象方法(哪怕方法体是空的,但是子类即将覆写(override))
但是在Delphi等单根继承的语言中,把接口做成抽象类会受到单根限制,而多个接口则可以被同一类实现,这点和C#、Java等都一样。李维的Inside VCL和罗小平的Delphi精要都有相关的介绍。
Delphi 7和之前版本的接口和COM有着许多联系,详见Inside VCL和ERIC HARMON的Delphi深入COM编程
下面是Delphi精要中的一个例子type
IShowString = interface(IUnknown)
procedure ShowString(S: String);
end;
TIObject = class(TObject, IShowString)
procedure ShowString(S: String);
end;
===========================================================================
type
IShowString = interface(IUnknown)
procedure ShowString(S: String);
end;
TComponent1 = class(TComponent, IShowString)
protected
procedure ShowString(S: String); virtual;
end;
TComponent2 = class(TComponent1)
protected
procedure ShowString(S: String); override;
end;
===========================================================================
var
IShowStr: IShowString;
begin
//类和它们实现的接口是兼容的
IShowStr := TComponent2.Create(nil);
IShowStr.ShowString('dd');
//接口引用计数方法会最终销毁接口所属的对象,所以我们不需要显式销毁对象。我们下面会详细讲述这个问题。
end;
谢谢!
大爱啊 谢谢啦 [email protected]
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
btn1: TButton;
btn2: TButton;
btn3: TButton;
btn4: TButton;
procedure btn4Click(Sender: TObject);
procedure btn1Click(Sender: TObject);
procedure btn2Click(Sender: TObject);
procedure btn3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; IMyinterface1 = interface
function Func1: Integer;
function Func2: Integer;
end; IMyInterface2 = interface
procedure Proc1;
procedure Proc2;
end; TMyClass1 = class(TInterfacedObject, IMyinterface1, IMyInterface2)
public
procedure Proc1;
procedure proc2;
function Func1: Integer;
function Func2: Integer;
end;var
Form1: TForm1;implementation{$R *.dfm}
{
1、接口命名约定 I起头, 就像类从T打头一样
2、接口都是从Interface继承而来,若是从根接口继承可省略
3、接口成员只能是方法、属性、没有字段
4、接口成员都是公开的,不需要private、protected、public、published等任何限制
5、因为接口只声明、无实现,也用不到继承与覆盖相关的修饰
6、一个接口可以从另一个接口继承,但不能从多个接口继承
7、一个类可以实现多个接口:TMyClass = Class(父类,接口1,接口2,接口3,..) end;
8、不论实现接口的类有多么丰富,接口只拥有自己声明的成员
9、实现接口的类一般继承于TinterfacedObject,直接从TObject继承会增加一些麻烦而重复的工作
10、接口在用完后会自己释放,并透视释放拥有它的类,这很方便,但同时带来很多问题}
procedure TForm1.btn1Click(Sender: TObject);
Var
c : TMyClass1;
begin
c := TMyClass1.Create;
c.Func1;
c.Func2;
c.Proc1;
c.proc2;
c.Free;
end;procedure TForm1.btn2Click(Sender: TObject);
var
i1 : IMyinterface1;
begin
i1 := TMyClass1.Create;
i1.Func1;
i1.Func2;
end;procedure TForm1.btn3Click(Sender: TObject);
var
i2 : IMyInterface2;
begin
i2 := Tmyclass1.Create;
i2.Proc1;
i2.Proc2;
end;procedure TForm1.btn4Click(Sender: TObject);
Var
c: TMyClass1;
i1: IMyinterface1;
i2: IMyInterface2;
begin
C := TMyClass1.Create;
i1 := c;
i1.Func1;
i1.Func2; i2 := c;
i2.Proc1;
i2.Proc2;
end;{ TMyClass1 }function TMyClass1.Func1: Integer;
begin
ShowMessage('imyinterface1.func1');
Result := 0;
end;function TMyClass1.Func2: Integer;
begin
ShowMessage('imyiterface1.func2');
Result := 0;
end;procedure TMyClass1.Proc1;
begin
ShowMessage('imyiterface2.proc1');
end;procedure TMyClass1.proc2;
begin
ShowMessage('imyiterface2.proc2');
end;
end.
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
btn1: TButton;
btn2: TButton;
btn3: TButton;
btn4: TButton;
procedure btn1Click(Sender: TObject);
procedure btn2Click(Sender: TObject);
procedure btn3Click(Sender: TObject);
procedure btn4Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; IMyinterface = interface
procedure proc;
end; TMyClass = class(TInterfacedObject, IMyinterface)
public
constructor create;
destructor Destroy; override;
procedure Proc;
end;var
Form1: TForm1;implementation{$R *.dfm}{ TMyClass }constructor TMyClass.create;
begin
inherited;
ShowMessage('Tmyclass.create');
end;
destructor TMyClass.Destroy;
begin
ShowMessage('Tmyclass.destroy');
inherited;
end;procedure TMyClass.Proc;
begin
ShowMessage('IMyInterface.Proc');
end;procedure TForm1.btn1Click(Sender: TObject);
Var
c : TMyClass;
begin
c := TMyClass.create;
c.Proc;
c.Free;
ShowMessage('*************');
end;procedure TForm1.btn2Click(Sender: TObject);
Var
i:IMyinterface;
begin
i := TMyClass.create;
i.proc;
ShowMessage('*************');
end;procedure TForm1.btn3Click(Sender: TObject);
Var
c : TMyClass;
i : IMyinterface;
begin
c := TMyClass.create;
i := c;
// i := Imyinterface(c); 也可以这样转换
// i := c as Imyinterface;{暂时不能使用as,接口拥有Guid后才可以使用as转换}
i.proc;
ShowMessage('***************');
end;procedure TForm1.btn4Click(Sender: TObject);
Var i:IMyinterface;
begin
i := TMyClass.create;
i.proc;
i := nil; //可以这样主动释放接口,同时拥有它的类也会释放
showMessage('************');
end;end.
都是以前自己练习时写的,接口封装还是非常不错,用dll文件写供调用的接口,分割也不错
我也有需要[email protected]
谢谢!
方便我们使用并调用即可
我发现要把具体代码贴上来还比较麻烦。
我也要书啊, 发我一本吧,
谢谢了, [email protected]
我也要书啊, 发我一本吧,
谢谢了, [email protected] 也来一本