王朝网络
分享
 
 
 

【Gabing Delva 第2篇】

王朝delphi·作者佚名  2006-01-09
宽屏版  字体: |||超大  

二、接口—2004.03.29~2004.03.30

接口,这个词最初接触时,我对这个词义很难理解。因为它听起来更像与硬件相关的。还有一个词COM,它代表的意思就更乱,不同领域里出现的COM一词大不相同。但在明白接口一词其理后,我还得说译得很恰当,形象地说明了它的本质和用途。只是伟大、丰富的汉语表意太深。

为什么要用接口呢?不用不行吗?我没资格给你答案,但我知道接口的出现起码解决了如下问题。我们都知道,Delphi和Java都不支持C plus plus可以支持的多重继承。Delphi规定一个类只能有一个父类,这是VCL树能流畅而为唯美地展现的根本。Java的追求是稳定,它更不可能让我们随便多重继承。那我们如果想继承太极的意又要继承少林的形怎么办呢?这就是接口要做的事。另外,接口是一种机制,在Delphi这种先声明,后实现的语言里,更显个性。因为,接口只声明/定义方法,而不实现。在Java中abstract类似乎可以替代接口,但我的理解是后者在继承层次增加后会突显其整洁的优势。

在Delphi里,从Delphi3加进了接口,并逐渐用它丰富了VCL,到了Delphi5时,Borland的接口技术在RAD中已趋于完美。嗯,当然,Delphi5是RAD最好的版本。以后的版本转向了在Web功能的丰富,大名鼎鼎的Web Service技术Delphi就是用接口实现的。5.0以前,接口的老祖宗是IUnknown,看上去就知道这是针对MicroSoft的那个我刚提过的,讨厌的名词COM的。在Delphi6推出时,正值Linux狼烟四起, Borland为了跨平台战略而大肆宣扬Kylix,这个祖宗变换了个大号,叫IInterface。我就是从那时起,知道了Kylix,看到了接口的广泛应用。

我们都知道,Delphi中的对象不能自动去活,它没有Java和C Sharp的垃圾回收机制。据李维先生说,Delphi之父Anders Hejelsberg当初设计Delphi时,让对象变量写入堆中而不是堆栈里,就是想在日后让Delphi可以自动回收闲置的对象。而直至今日,Danny Thorpe也没有让Delphi实现这个功能(虽然没有自动回收的Delphi已经几近完美)。反倒Anders Hejelsberg在到微软后实现了自己的想法,因为c sharp里已经实现了这个功能。可见C Sharp是Anders未尽理想的续篇。

嘿嘿,既然是闲谈,难免跑题。说自动去活是想说在Delphi里,接口是可以自动去活的。接口的对象计算引用数,使内存的管理自动化。Delphi的程序员更得了解引用技术值(Reference Count)。

下面就看看在Delphi里的接口吧。

我们先定义好接口和类:

type

IMyidol=interface

['{30DDAB80-81BF-11D8-A27B-930F92738A22}'] //shift+ctrl+G 生成GUID

procedure name(s:string); //接口方法不能实例化

procedure others;

end;

type

TAnders=class(TInterfacedObject,IMyidol)

//继承一个通用类TInterfacedObject,并实现接口Imyidol。

procedure name(s:string); //shift+ctrl+C

procedure others;

end;

然后实现:

procedure TAnders.name(s: string); //shift+ctrl+C 自动产生

begin

Form1.edit1.Text:=s;

end;

procedure TAnders.others;

begin

end;

procedure TForm1.Button1Click(Sender: TObject);

var

Anders:TAnders;

begin

Anders:=TAnders.Create;

Anders.name('Anders Hejlsberg!');

Anders.Free;

end;

procedure TForm1.Button2Click(Sender: TObject);

var LiWei:IMyidol;

begin

LiWei:=TAnders.Create;

LiWei.name('LiWei!'); //不必Free;

end;

这是效果图。

紧接着我们再来看看在Java中如何实现接口,然后我们再来对比着聊一聊。

interface Myidol{

void name(String s);

void others();

}

class SuperMan{ //定义一个类

}

class Man extends SuperMan implements Myidol{

//extends继承父类;implements实现接口。这里为了演示,其实可以不继承。

public void name(String s){

System.out.println(s);

}

public void others();

}

public class Do{

public static void main(String[] args){

Man man=new Man();

man.name("Anders Hejlsberg!");

}

}

看看效果图吧。

我们看到。Delphi的类在声明时不能写具体怎么实现,而要到implementation后面去写实现语句。而Java就不用这么“麻烦”,想到哪里就写到哪。这是他们的各自特点。也正因此,一个严谨,一个灵活。还有一个问题是,类可以继承多个接口。那接口可不可以继承多个接口呢?Java里的答案是肯定的,而Delphi7告诉你还的等,呵呵。可见,Java对接口的实现是最完美的。另外,Java没有Delphi的GUID,因为它不需要支持COM,也不需要像Delphi那样从祖宗接口继承。

回过头,观察一下代码我们会发现,others方法多余的,但还是在Delphi和Java里都写了空代码。此举多余乎?不多也。其实,接口有些私心,它让继承它的类必须一并实现它的方法,不然这个类就只能是适配器类或抽象类。哎,记住这一点吧。所以我在Delphi里没敢创建TsuperMan这个类,而是用通用的类TinterfacedObject。不然,我就得去实现这些:QueryInterface 、_AddRef、 _Release因为这是接口的老祖宗定义的。什么,连接口祖宗八代定义的方法都要在这个刚刚诞生的新类中去实现?是的。幸亏有TinterfacedObject这样的类。我们来看看它。

TInterfacedObject = class(TObject, IInterface)

protected

FRefCount: Integer;

function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;

function _AddRef: Integer; stdcall;

function _Release: Integer; stdcall;

public

procedure AfterConstruction; override;

procedure BeforeDestruction; override;

class function NewInstance: TObject; override;

property RefCount: Integer read FRefCount;

end;

还有就是接口定义的所有方法都是公开的,接口中的常量都是public static和final,而且这些是不必说明的。

最后我们再来研究一下如何取得接口并调用它的服务。

var LiWei:IMyidol;

begin

LiWei:=TAnders.Create; //Tanders的对象制定给了接口LiWei。

LiWei.name('LiWei!'); //调用name方法。

这是种隐式的操作方式,再来看看更明确的写法:

var Anders:TAnders; LiWei:IMyidol;

begin

Anders:=TAnders.Create; //生成对象。

LiWei:= Imyidol(Anders);

LiWei.name('LiWei!');

要说明的是,Anders必须支持Imyidol,不然报错。

还可以这样写:

var Anders:TAnders; LiWei:IMyidol;

const ILiWei:TGUID='{30DDAB80-81BF-11D8-A27B-930F92738A22}';

begin

Anders:=TAnders.Create; //生成对象。

if Anders.GetInterface(ILiWei,LiWei) then

LiWei.name('LiWei!');

end;

在Java中的情形是一样的:

Man man=new Man();

man.name("Anders Hejlsberg!"); //这是类对象实现的方式。

Myidol lw=new Man();

lw.name("LiWei!"); //这是接口实现方式。

聊到这里,相信我们都对接口有了一定认识。不过接口的话题太大了,牵扯的东西也非常多,所以不可能聊得太深太远。是不是聊得有点口渴了?快去喝点绿茶吧,比咖啡解渴。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有