从Delphi3开始支持接口。接口定义了能够与一个对象进行交互操作的一组过程和函数。对一个接口进行定义包含两个方面的内容:

1)一方面是实现这个接口

2)另一方面是定义接口的客户

  一个类能够实现多个接口,即提供多个让客户用来控制对象的“表现方式”

  正如名字所表现的,一个接口就是对象和客户通信的接口。这个概念就像C++中的 pure virtual类。实现接口的函数和过程就是支持这个接口的类的工作。

一、定义接口

  就像多有的Delphi类都派生于TObject一样,所有的接口都派生于一个称谓IUnKnown的接口,IUnKnown在system单元中定义如下

type
IUnKnown = interface
    ['{00000000-0000-0000-C000-000000000046}']
function QueryInterface(const IID: TGUID; out Obj): Integer; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
end;

  

  接口的定义就像是类的定义,最根本的不同是在接口中有一个全局唯一标识符(GUID),它对应每一个接口而言都是不同的。对于IUnKnown的定义来自于MicroSoft的组件对象模型(COM)

规范。

  如果你知道怎么创建Delphi的类,那么定义一个定制的接口是一件简单的事情,下面的代码定义了一个新的接口IFoo,它包含一个称为F1()的方法

type
IFoo = interface
    ['{2137B60-AA33-11D0-A9BF-9A537A42701}']
function F1: Integer;
end;

  提示:在Delphi的IDE中,按Ctrl+Shift+G快捷键,就可以为接口生成一个新的GUID

  下面的代码声明了一个称为IBar的接口,它是从IFoo接口继承来的

type
IBar = interface(IFoo)
['{2137BF61-AA33-11D0-A9BF-9A4537A42701}']
function F2: Integer;
end;

  

二、实现接口

  下面的代码演示了在一个类TFooBar中怎么实现IFoo和IBar接口

type
TFooBar = class(TInterfacedObject, IFoo, IBar)
function F1: Integer;
function F2: Integer;
end; function TFooBar.F1:Integer;
begin
Result:= 0;
end; function TFooBar.F2: Integer;
begin
Result:= 0;
end;

  一个类实现接口的时候,一定要在class的括号里面加上这个类:TInterfacedObject

  注意,一个类可以实现多个接口,只要在声明这个类的时候,一次列出要实现的接口。编译器通过名称来把接口中的方法与实现接口中的类中的方法对应起来,如果一个类只是声明要实现某个接口,但并没有具体实现这个接口中的方法,编译将会出错

  如果一个类要实现多个接口,而这些接口中包含同名方法,必须把同名的方法另取一个别名,例子

type
IFoo = interface
['{21313134-DE23-1213-1123-A328301232}']
function F1: Integer;
end; IBar = interface
['{21313134-DE23-1213-1123-A32DE01232}']
function F1: integer;
end; TFooBar = class(TInterfaceObject, IFoo, IBar)
//为同名方法取别名
function IFoo.F1 = FooF1;
function IBar.F1 = BarF1;
//接口方法
function FooF1: Integer;
function BarF1: Integer;
end; function TFooBar.FooF1: Integer;
begin
Result:= 0;
end; function TFooBar.BarF1: Integer;
begin
Result:= 0;
end;

  

三、implements指示符

  implements指示符是在Delphi4中引进的,它的作用是委托另一个类或者接口实现接口中的某个方法这个技术有时又被称为委托实现,关于 implements指示符的用法,请看下面的代码:

type
TSomeClass = class(TInterfacedObject, IFoo)
function GetFoo: TFoo;
property Foo: TFoo read GetFoo implements IFoo;
end;

  在上面的例子中的implements指示符是要求编译器在Foo属性中寻找实现IFoo接口方法。属性的类型必须是一个类,它包含IFoo方法或者类型是IFoo的接口后或者IFoo派生接口。implements指示符后面可以列出几个接口,彼此用逗号隔开

  implements指示符在开发中提供了两个好处:

1)首先,它允许以无冲突的方式进行接口聚合。聚合是COM中的概念,它的作用是把多个类合在一起共同完成一个任务。

2)其次,它能够延后占用实现接口所需的资源,知道确实需要资源。例如,假设实现一个接口需要分配一个1MB的位图,但是这个接口很少用到,因此,可能平时你不想实现这个接口,因为它太耗费资源了,用implements指示符之后,可以只在属性被访问时才创建一个类来实现接口

四、使用接口

  当在应用程序中使用接口类型的变量时,要用到一些重要的语法规则。最需要记住的是,一个接口是生存期自管理类型的,这就意味着,它通常被初始化为NIL,它是引用计数的,当获得一个接口时自动增加一个引用计数;当它离开作用域或者赋值为NIL时它被自动释放。下面的代码演示一个接口变量的生存期自管理机制

var
I : ISomeInterface;
begin
//I被初始化为NIL
I:= FunctionReturningAnInterface; //I的引用计数加1
I.SomeFunc;
// I 的引用计数减1,如果为0,则自动释放
end;

  关于接口变量的另一个规则是,一个接口变量与实现这个接口的类是赋值兼容的,例如,下面的代码是合法的:

procedure Test(FB: TFooBar)
var
F:IFoo;
begin
F:= FB; //合法,因为FB支持IFoo
..
..

  最后,类型强制转换运算符as可以把一个接口类型的变量强制类型转换为另一个接口,例子

var
FB: TFooBar;
F: IFoo;
B IBar;
begin
FB:= TFooBar.Create;
F:= FB; //合法,因为FB支持IFoo
B:= F as IBar; //合法,把F转换为IBar
..

  

Delphi面向对象---接口的更多相关文章

  1. Delphi 的接口机制——接口操作的编译器实现过程(1)

    学习COM编程技术也快有半个月了,这期间看了很多资料和别人的程序源码,也尝试了用delphi.C++.C#编写COM程序,个人感觉Delphi是最好上手的.C++的模版生成的代码太过复杂繁琐,大量使用 ...

  2. delphi中接口的委托和聚合

    Delphi的TRegistry注册表类 方法详解 Delphi的接口编程入门 delphi中接口的委托和聚合 2009-09-27 10:44:44|  分类: 默认分类 |  标签: |举报 |字 ...

  3. Java 基础 面向对象: 接口(interface )概念 以及接口之练习3 -定义一个接口用来实现两个对象的比较并 判断instanceof是否为同类

    接口(interface )概念概念笔记 及测试代码: /** 面向对象: 接口(interface ) 是与类并行的一个概念: * 1.接口可以看成一个特殊的抽象类,它是常量与抽象方法的一个集合 * ...

  4. 静态成员、final成员、面向对象接口

    静态成员 静态属性定义时在访问控制关键字后面加static 在类定义中使用静态成员的时候,用self关键字后面跟着::操作符,在访问静态成员的时候::后面需要跟$符号 在类定义外部访问静态属性,用类名 ...

  5. 面向对象-接口(interface)实战案例

    面向对象-接口(interface)实战案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.接口(interface)概述 1>.接口的语法格式 接口时抽象类的一种特殊体 ...

  6. Delphi面向对象编程

    一.面向对象介绍 OOP是使用独立的对象(包含数据和代码)作为应用程序模块的范例.虽然OOP不能使得代码容易编写,但是它能够使得代码易于维护.将数据和代码结合在一起,能够使定位和修复错误的工作简单化, ...

  7. Delphi面向对象的编程思想

    第一章.建立面向对象的新思维 1.1.1历史背景 目前对象技术的前沿课题包括设计模式.分布式对象系统.和基于网络的对象应用等 目前面向对象的语言包含4个基本的分支: 1.基于Smalltalk的:包括 ...

  8. Jser 设计模式系列之面向对象 - 接口封装与继承

    GOF在<设计模式>中说到:面向接口编程,而非面向实现编程 鉴于此,这个概念可见一斑! JS却不像其他面向对象的高级语言(C#,Java,C++等)拥有内建的接口机制,以确定一组对象和另一 ...

  9. Delphi 的接口机制——接口操作的编译器实现过程(2)

    接口对象的内存空间 假设我们定义了如下两个接口 IIntfA 和 IIntfB,其中 ProcA 和 ProcB 将实现为静态方法,而 VirtA 和 VirtB 将以虚方法实现: IIntfA =  ...

随机推荐

  1. SQL手册

    来自 W3School 的 SQL 快速参考.可以打印它,以备日常使用. SQL 语句 语句 语法 AND / OR SELECT column_name(s)FROM table_nameWHERE ...

  2. PYTHON 集合set 方法

    集合是一个无序的,不重复的数据组合,它的主要作用如下: 去重,把一个列表变成集合,就自动去重了 关系测试,测试两组数据之前的交集.差集.并集等关系 常用操作 a = set([1,2,3,4,3,4] ...

  3. C++中各种容器特点总结

    1.vector 内部数据结构:数组,可随机访问元素,在末尾增加或删除元素与元素数目无关,在其 他部分增加或删除元素随着元素数目呈线性变化. 2.deque 数组,按页/块来分配存储,每页/块包含固定 ...

  4. centos 设置永久dns

    最近在折腾一个问题. 由于服务器的带宽是联通5M, 不稳定.而且所处的网络的dns解析貌似老出问题,每隔一定周期解析时间特别长. 于是乎,想在本地做一个dns,这样可以减少dns解析时间,并做些静态配 ...

  5. 应用HTK搭建语音拨号系统4: 识别器评估

    选自:http://maotong.blog.hexun.com/6261890_d.html 苏统华 哈尔滨工业大学人工智能研究室 2006年10月30日 声明:版权所有,转载请注明作者和来源 该系 ...

  6. Django CRM __contains与__icontains区别

    http://www.yihaomen.com/article/python/199.htm operators = { 'exact': '= %s', 'iexact': 'LIKE %s', ' ...

  7. js控制精度的加减乘除:js浮点数计算问题

    //加法函数 function accAdd(arg1, arg2) { var r1, r2, m; try { r1 = arg1.toString().split(".")[ ...

  8. CCF 最优配餐 (BFS)

    问题描述 栋栋最近开了一家餐饮连锁店,提供外卖服务.随着连锁店越来越多,怎么合理的给客户送餐成为了一个急需解决的问题. 栋栋的连锁店所在的区域可以看成是一个n×n的方格图(如下图所示),方格的格点上的 ...

  9. 如何获得images.xcassets 中图片的路径?

    UIImage加载图片的方式以及Images.xcassets对于加载方法的影响 重点: Images.xcassets中的图片资源只能通过imageNamed:方法加载,通过NSBundle的pat ...

  10. IOS-UIIamge初始化的几种方法的比较

    一.imageNamed——方法介绍imageNamed:是UIImage的一个类方法,它做的事情比我们看到的要稍微多一些.它的加载流程如 下:1.系统回去检查系统缓存中是否存在该名字的图像,如果存在 ...