从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. VB .NET周期实现

    这里仅提供一个方案,当然会有比本方案更好的,欢迎提供. 简介 在vb.net实现周期调度的问题时(就是间隔固定的时间做什么事情),我们最先想到的一定是(反正我是)利用timer(定时器)来做这个计时的 ...

  2. 项目: 推送水木文章到Kindle

    代码在github:https://github.com/Viyu/PushNewsmth2Mail 当年买Kindle的时候,想再Kindle上阅读水木的帖子,但Kindle的Web上网体验太差,想 ...

  3. ssh免密码登入

    通常做许多事情(git puh/脚本等等),不停输入密码是件很不愉快的事情,破解如下: http://www.linuxproblem.org/art_9.html 1. 生成rsa密钥 ssh-ke ...

  4. 浅析mongoEngine的document对象

    引言: from mongoengine import * connect('local')class Test(Document): name=StringField(max_length=32) ...

  5. 转:js中this关键字详解

    this指向哪里? 一般而言,在Javascript中,this指向函数执行时的当前对象. In JavaScript, as in most object-oriented programming ...

  6. PHP使用curl替代file_get_contents

    初学php的朋友们,很容易翻一个错误,在写采集程序或者调用api接口总会有线考虑到使用file_get_contents函数来或许内容,程序的访问量不大倒是没什么影响,但是访问量提升了那非常的悲剧了, ...

  7. Java RuntimeException异常处理汇总

    Java中所有异常的父类是Throwable类,在Throwable类下有两大子类: 一个是Error类,指系统错误异常,例如:VirtualMachineError 虚拟机错误,ThreadDeat ...

  8. maven加载本地lib下的jar包

    1.本地lib下有jar 2.命令: mvn install:install-file -Dfile=juh-3.0.1.jar -DgroupId=org.openoffice -Dartifact ...

  9. LeetCode 441 Arranging Coins

    Problem: You have a total of n coins that you want to form in a staircase shape, where every k-th ro ...

  10. codeforces gym 100286 H - Hell on the Markets (贪心算法)

    题目链接 题意:n个数分别为a[i],问是否存在一组对应的b[i],b[i]=1 || b[i]=-1,使得ai*bi的n项和为0. 题解: 先证明一个结论吧,对于1≤ai≤i+1,前面ai个数一定可 ...