Delphi面向对象---接口
从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面向对象---接口的更多相关文章
- Delphi 的接口机制——接口操作的编译器实现过程(1)
学习COM编程技术也快有半个月了,这期间看了很多资料和别人的程序源码,也尝试了用delphi.C++.C#编写COM程序,个人感觉Delphi是最好上手的.C++的模版生成的代码太过复杂繁琐,大量使用 ...
- delphi中接口的委托和聚合
Delphi的TRegistry注册表类 方法详解 Delphi的接口编程入门 delphi中接口的委托和聚合 2009-09-27 10:44:44| 分类: 默认分类 | 标签: |举报 |字 ...
- Java 基础 面向对象: 接口(interface )概念 以及接口之练习3 -定义一个接口用来实现两个对象的比较并 判断instanceof是否为同类
接口(interface )概念概念笔记 及测试代码: /** 面向对象: 接口(interface ) 是与类并行的一个概念: * 1.接口可以看成一个特殊的抽象类,它是常量与抽象方法的一个集合 * ...
- 静态成员、final成员、面向对象接口
静态成员 静态属性定义时在访问控制关键字后面加static 在类定义中使用静态成员的时候,用self关键字后面跟着::操作符,在访问静态成员的时候::后面需要跟$符号 在类定义外部访问静态属性,用类名 ...
- 面向对象-接口(interface)实战案例
面向对象-接口(interface)实战案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.接口(interface)概述 1>.接口的语法格式 接口时抽象类的一种特殊体 ...
- Delphi面向对象编程
一.面向对象介绍 OOP是使用独立的对象(包含数据和代码)作为应用程序模块的范例.虽然OOP不能使得代码容易编写,但是它能够使得代码易于维护.将数据和代码结合在一起,能够使定位和修复错误的工作简单化, ...
- Delphi面向对象的编程思想
第一章.建立面向对象的新思维 1.1.1历史背景 目前对象技术的前沿课题包括设计模式.分布式对象系统.和基于网络的对象应用等 目前面向对象的语言包含4个基本的分支: 1.基于Smalltalk的:包括 ...
- Jser 设计模式系列之面向对象 - 接口封装与继承
GOF在<设计模式>中说到:面向接口编程,而非面向实现编程 鉴于此,这个概念可见一斑! JS却不像其他面向对象的高级语言(C#,Java,C++等)拥有内建的接口机制,以确定一组对象和另一 ...
- Delphi 的接口机制——接口操作的编译器实现过程(2)
接口对象的内存空间 假设我们定义了如下两个接口 IIntfA 和 IIntfB,其中 ProcA 和 ProcB 将实现为静态方法,而 VirtA 和 VirtB 将以虚方法实现: IIntfA = ...
随机推荐
- hiho #1326 : 有序01字符串
#1326 : 有序01字符串 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于一个01字符串,你每次可以将一个0修改成1,或者将一个1修改成0.那么,你最少需要修改 ...
- DMZ
DMZ是英文“demilitarized zone”的缩写,中文名称为“隔离区”,也称“非军事化区”.它是为了解决安装防火墙后外部网络的访问用户不能访问内部网络服务器的问题,而设立的一个非安全系统与安 ...
- 解决ubuntu下安装mysql使用service无法启动问题
启动的时候发现service mysql start Rather than invoking init scripts through /etc/init.d, use the service(8) ...
- mysql+mybatis+存储过程+事务 + 多并发流水号获取
数据库存储过程 drop PROCEDURE generate_serial_number; CREATE PROCEDURE generate_serial_number( ), IN param_ ...
- Js 的 this 是什么
this指的是调用函数的那个对象,谁调用函数,谁就是this 更多: http://www.cnblogs.com/justany/archive/2012/11/01/the_keyword_thi ...
- [转]JVM内存堆布局图解分析
JAVA能够实现跨平台的一个根本原因,是定义了class文件的格式标准,凡是实现该标准的JVM都能够加载并解释该class文件,据此也可以知道,为啥Java语言的执行速度比C/C++语言执行的速度要慢 ...
- 快速搭建VPN服务器
http://www.ttlsa.com/linux/centos-install-pptp-vpn/
- jQuery获取循环中的选中单选按钮radio的值
1.<input type="radio" name="testradio" value="jquery获取radio的值" /> ...
- Apache2.4.6 添加虚拟主机
apache2.4 与 apache2.2 的虚拟主机配置写法有所不同 apache2.2的写法: <VirtualHost *:80> ServerName domain.com Doc ...
- (转载)linux中设备文件配置程序udev详解
如果你使用Linux比较长时间了,那你就知道,在对待设备文件这块,Linux改变了几次策略.在Linux早期,设备文件仅仅是是一些带有适当的属性集的普通文件,它由mknod命令创建,文件存放在/dev ...