注册 | 登录
收藏 | 帮助
热门文章
编辑推荐
相关文章  
从Melissa到Zotob:Windows蠕虫1
从后台得到webshell技巧大汇总
Qmail邮件系统下防止滥用mail re
Qmail邮件系统下防止滥用mail re
使用telnet 方式连接Imail的SMTP
MDeamon Server 邮件系统迁移完全
用RelayFax搭建传真服务器
Qmail邮件系统下防止滥用mail re
隐藏qmail的SMTP help信息保护你
Sendmail的relay用法汇总
您现在的位置: 顶尖设计 >> IT学院 >> 编程开发 >> Delphi >> 文章正文
Delphi下的接口编程学习笔记(原创)
作者:IceAir  来源:csdn  点击:  更新:2006-12-19
简介:
Delphi下的接口编程     Delphi下的接口编程学习笔记 1.1  为什么使用接口?     举个例子好了:有这样一个卖票服务,电影院可以卖票,歌剧院可以卖票,客运站也可以卖票,那么我们是否需要把电影院、、歌 剧院和客运站都设计成一个类架构以提供卖票服务?要知道,连经理人都可以卖票,很显然不适合把经理人也包括到卖票服务的继承架构 中,我们需要的只是一个共通的卖票服务。于是,卖票的服务是个接口,电影院、歌剧院什么的只要都遵循这样一个服务定义就能很好地 相互交互和沟通(如果须要的话)。       1.2  如何在Delphi中使用接口         1.2.1  声明接口             IMyInterface = interface(IInterface)  //说明(1)             ['{63E072DF-B81E-4734-B3CB-3C23C7FDA8EA}']  //说明(2)                 function GetName(const str: String): String; stdcall;                   function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; //说明(3)                 function _AddRef: Integer; stdcall;  //使接口引用数加1。                 function _Release: Integer; stdcall;//使接口引用数减1,当小于等于0时作释放动作。             end;                          说明(1):如果有继续关系则在括号里填父接口,否则省却,如:IMyInterface = interface这样就行。             说明(2):此GUID可选,如果要实现具有COM特性的接口的话则需要加上,Delphi中对于有GUID的接口在运行时在VMT表的                          预定位置生成接口的信息,如接口方法的定义、方法参数定义能详细信息。             说明(3):接口必须实现这三个函数。           1.2.2  接口的实现             接口服务是由类来实现的。                 TIntfClass = class(TObject, IMyInterface)                 private                     FCounter: Integer;                     FRefCount: Integer;                 public                     function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;                     ...                 end;           1.2.3  获取接口                 a. 使用类型转换。                         如:var aIntf: IMyInterface;                         begin                             aObj := TIntfClass.Create;                             try                                 aIntf := (IMyInterface(aObj);                                 ...                 b. 利用Delphi编译器内建机制。 如:aIntf := aObj。                 c. 利用对象的QueryInterface方法。如OleCheck(aObj.QueryInterface(IID, aIntf)); 只能存取有GUID的COM接口。                 d. 利用as操作符。                         使用as操作符必须符合下面条件:1.接口必须明确地指定是从IInterface接口继承下来。2.必须拥有GUID值                     在Delphi7中接口的实现类还必须是从TInterfacedObject继承下来才行,如                     TIntfClass = class(TInterfacedObject, IMyInterface)           1.2.4  接口和对象生命期                            因为Delphi会自行检查接口如果在使用后没有释放而在生成的程序里加上释放代码,但也因这样带来了问题,如下面代码: var   i: Integer;   aObj: TIntfClass;   aIntf: IMyInterface; begin   aObj := TIntfclass.Create;   try      aIntf := aObj;      aIntf.GetName...   finally      aIntf := nil;      FreeAndNil(aObj);   end;     上面的代码执行的话会产生存取违规错误,是因为对接口置nil时已释放接口,而FreeAndNil(aObj)会再释放aIntf一次,而在对aIntf置 nil时已释放了该对象。解决这个问题只要不让接口干扰对象的生命期就可以了,在Release中只需减引用计数而不做释放的动作。 function TIntfClass._Release: Integer; begin     Result := InterlockedDecrement(FRefCount); end;             1.2.5  接口的委托(Interface Delegation)             分为两种:1. 对象接口委托    2. 类对象委托。         . 对象接口委托,假如已有下面接口定义: IImplInterface = interface(IInterface)     function ConvertToUSD(const iNTD: Integer): Double;     function ConvertToRMB(const iNTD: Integer): Double; end;   接着有一个类实现了该接口: TImplClass = class(TObject, IImplInterface) private    FRefCount: Integer; public   function ConvertToUSD(const iNTD: Integer): Double;   ... end;   implementation   function TImplClass.QueryInterface(const IID: TGUID; out Obj): HResult; begin     if GetInterface(IID, Obj) then        Result := 0     else        Result := E_NOINTERFACE; end;   function TImplClass._Release: Integer; begin     Result := InterlockedDecrement(FRefCount);     if Result = 0 then       Destroy; end; ... ...   现在有另外一个类TIntfServiceClass要实现IImplInterface接口,不用重新定义,只须使用上面的TImplClass就可以: TIntfServiceClass = class(TObject, IImplInterface) private     FImplService: IImplInterface;     //FSrvObj: TImplClass;   //如果是用类对象委托的话 public     Constructor Create; overload;     Destructor Destroy; override;     Constructor Create(aClass: TClass); overload;     property MyService: IImplInterface read FImplService implements IImplInterface;    // property MyService: TImplClass read FSrvObj implements IImplInterface; //如果是用对象委托的话。 end;   实现如下: constructor TIntfServiceClass.Create; begin     FImplService := TImplClass.Create; end;   constructor TIntfServiceclass.Create(aClass: TClass); var   instance: TImplClass; begin     instance := TImplClass(aClass.NewInstance);     FImplService := instance.Create; end;   destructor TIntfServiceClass.Destroy; begin     FImplService := nil;  //遵照TImplClass使用引用计数来控制对象生命周期,看TImplClass的Destroy实现。     inherited; end;       1.2.6  接口和RTTI         Delphi中在VMT-72

[1] [2] 下一页






  • 上一篇文章:
  • 下一篇文章:
  • 分享此文:该页面添加到 Mister Wong 添加到雅虎Yahoo!收藏 Add to:Del.icio.us Post to Furl Digg this 添加到Google书签 reddit spurl blogmarks 365Key 评论  收藏  分享  打印
     我来说两句
    姓名:       验证码:   
    主页: 
    评分: 1分 2分 3分 4分 5分
    本频道近期热评文章:
      关于我们 | 联系我们 | 站点地图 | 广告投放 | 友情链接 | 在线留言 | 版权申明
    版权所有 © 2004-2007 顶尖设计(bobd.cn)
    未经授权禁止转载,摘编,复制本站内容或建立镜像. 沪ICP备07504942号 
    网络110
    报警服务