,Delphi   工具软件   办公软件   操作系统   网络安全   设计在线   程序开发   教程宝典   软件下载   软件论坛,Delphi
您的位置:软件 > 开发者网络 > 开发工具 > 开发专栏 > Delphi > 正文
基于Delphi的接口编程入门
[文章信息]
作者:IceAir
时间:2005-04-13
出处:blog
责任编辑:方舟
[文章导读]
举个例子好了:有这样一个卖票服务,电影院可以卖票,歌剧院可以卖票,客运站也可以卖票
advertisement
热点推荐
· VB实现SQL Server 2000存储过程调用
· Java解析网络数据流的三种特殊方法
· 多媒体教程:网页表单文本域类型
· 体验V5E地形编辑:整体控制
· 打造完美可随意安装的WinXP镜像
[正文]

上一页  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;

  6、接口和RTTI

  Delphi中在VMT-72位移处定义了接口哥格指针:vmtIntfTable = -72。

  相关函数:

GetInterfaceCount; //获取接口数量。
GetInterfaceTable; //获取接口表格。

  相关结构:

TInterfaceEntry = packed record
IID: TGUID;
VTable: Pointer;
IOffset: Integer;
ImplGetter: Integer;
end;

PInterfaceTable = ^TInterfaceTable;
TInterfaceTable = packed record
EntryCount: Integer;
Entries: array[0..9999] of TInterfaceEntry;
end;

  Self是指向VMT指针的指针,所以:Self.GetInterfaceTable.EntryCount等价于:

aPtr := PPointer(Integeer((Pointer(Self))^) + vmtIntfTable)^;

  只要在声明中使用M+/M-指令就能在Delphi中编译出的程序里添加RTTI信息,如:

{$M+}
iInvokable = interface(IInterface)
{$M-}

  接口的RTTI信息由TIntfMetaData记录结构定义:

TIntfMetaData = record
name: String; //接口名称
UnitName: String; //接口声明的程序单元名称
MDA: TIntfMethEntryArray; //储存接口中方法信息的动态数组
IID: TGUID; //接口的GUID值
Info: PTypeInfo; //描述接口信息的指针
AncInfo: PTypeInfo; //描述父代信息的指针
NumAnc: Integer; //此接口继承自父代接口的方法数目
end;

  TIntfMethEntryArray的定义如下:

type
 TCallConv = (ccReg, ccCdecl, ccPascal, ccStdCall, ccSafeCall);
 TIntfMethEntry = record
 Name: String; //方法名称
 CC: TCallConv; //调用惯例
 Pos: Integer; //方法在接口中的位置
 ParamCount: Integer; //方法的参数数目
 ResultInfo: PTypeInfo; //描述方法回传类型的信息指针
 SelfInfo: PTypeInfo; //描述方法本身的信息指针
 Params: TIntfParamEntryArray; //描述参数信息的动态数组
 HasRTTI: Boolean; //这个方法是否拥有RTTI信息的布尔值
end;

TIntfMethEntryArray = array of TIntfMethEntry;

  参数信息TIntfParamEntry定义:

TIntfParamEntry = record
Flags: TParamFlags;
Name: String;
Info: PTypeInfo;
end;

TTypeInfo = record
Kind: TTypeKind; //数据类型
Name: ShortString; //类型信息的字符串格式
end;

上一页  1 2  

发表评论推荐给朋友我想参加相关培训打印我对此感兴趣订阅电子杂志
天极社区邀请您:写博客日记  上传相片   论坛聊天  订阅电子杂志  推荐网摘   免费图铃工具
笔名:   请您注意:

 遵守国家有关法律、法规,尊重网上道德,承担一切因您的行为而直接或间接引起的法律责任。

 天极网拥有管理笔名和留言的一切权利。
评论:
 
,Delphi相关内容,Delphi焦点新闻
  • 利用Delphi开发旅游景点微机售票系统
  • TXMLDocument类:Delphi7的XML利器
  • 基于Delphi的Socket I/O模型全接触
  • 用Delphi实现QQ窗体的缩入伸出功能
  • Delphi中用ICMP探测远程主机状态
  • FVD刺激高清碟机加速商业化 抢占商机最重要
  • 3家搜索引擎集体诉讼8848 吕春维未敢出席
  • 杨元庆:没有准备不会获批的备用方案
  • 军队信息化诞生新领域 电子军务呼之欲出
  • 世界经济论坛公布信息化程度全球最新排名
  • 2004政务绩效评估:政府门户尚处于发展阶段
  • 甲骨文出资5.15亿美元 意图收购RetekInc
  • 技术并购:帮你突破传统增长的“天花板”
  • ,DelphiAdvertisement