分享
 
 
 

【Gabing Delva 第1篇】

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

一、多态—2004.03.28

上大学那会儿,我曾经给一对双胞胎兄弟补过英文课。他俩的模样至今依然清晰。哥哥我给他取了个English Name叫David,他很好动,也很能讲;而弟弟Davis呢,有点腼腆,但很聪明,从接受能力上更好一点。性格上,David更像姜文,Davis更像姜武,呵呵,我喜欢的两个中国纯爷们儿!这是了解他们之后才发现的。最初见到他们时,我常常要问,你们谁是哥哥来着。

嗯,说起这件小事是为了聊一下delva中的多态。

先来聊聊重载问题(也叫超载,总之是那个Overload)吧。在同一个类中,出现多个同名的方法的现象就是Overload。联系起上面提到的兄弟俩,我想这更好理解。他们从外观上是相似的,不同的是某些“参数”,类型上可能各异或是个数上不同。

在Delphi中,所有方法都默认是静态的,便于编译器和链接器解析调用。为实现超载,要在方法明的后面加上关键字overload,不然会产生报错。先看个小例子吧:

type //这是Delphi对类Ta的定义部分

Ta=class

public

procedure XiongDi(age,height:integer);overload; //这是Ta的两个公共过程,名字一样

procedure XiongDi(name:string);overload; //但他们的参数不同。

end;

implementation //以下为实现部分

procedure Ta.XiongDi(age, height: integer); //这是两个过程的实现。

begin

Form1.Edit1.Text:='age: '+inttostr(age)+' height: '+inttostr(height);

end;

procedure Ta.XiongDi(name: string);

begin

Form1.Edit2.Text:='name: '+name;

end;

{Delphi用很强的图形化控件,我们用一个窗体的Button控件来激活上述过程,并用Edit控件显示结果。}

procedure TForm1.Button1Click(Sender: TObject);

var

a:Ta; //这是Delphi对对象的定义,a是Ta的实例化,就是Ta这个类的对象。

begin

a.XiongDi(15,130);

a.XiongDi('David');

这是效果图。

我们看到第一个XiongDi反映的是年龄和身高信息,而第二个XiongDi则反映的是姓名信息。它们的参数个数和类型都不同,要表达的效果也就不同。所以,面对Overload我们不要被表面上的名称所迷惑,而应该了解函数、过程和方法实质的作用。多说一句,函数和过程是Delphi里的叫法,Java中统成为方法,无返回值的方法用void关键字表示,代表Delphi里的过程,而有返回值的方法就是Delphi中的函数。

再来说说在Java中实现Overload。Java的方法和Delphi刚好相反,所有方法都默认成虚拟的,所以Java中可以随时Overload而不需要标明我要超载这个方法了。为了对比,我在Java中写个和上面一样的例子:

A.java文件:

class A{ //这是Java中对类A的定义。

public void XiongDi(int age,int high){ //这里定义了两个同名方法

System.out.println("age: "+age+" high: "+high);

}

public void XiongDi(String name){

System.out.println(name);

}

}

Do.java文件:

public class Do{

public static void main(String[] args){

A a=new A();

a.XiongDi(15,130);

System.out.println(" **********");

a.XiongDi("David");

}

}

编译并执行的结果。

好了,到此我们对delva的overload算是有了一个感性的认识了。我们可以看到,重载事发生在同一个类中,不同方法之间的现象。就像两兄弟之间一样。呵呵,如果是父子之间又会发生什么有趣的现象呢?

投掷,这个从我们祖先继承下来的动作,因人而异。比如,我的爸爸投掷东西时是用右手,而我是个左撇子。这种动作相同而执行方式不同的现象就是下面我们要聊的覆盖(又叫改写,就是Override)。嘿嘿,Overload、Override,我们中国人看到这两个相似的单词,最初都有些迷惑,就像老外看到横戌点戍空心戊一样,而他们其实大不相同。覆盖事发生在父类和子类的方法之间的。我们聊到这里就决不会再弄混这两个名词了。但我要说的是,他们还是有联系的。那就是他们同为面向对象编程的主要特点,是包装、继承和多态三大要素中,多态的具体表现。

闲话少叙,就先在Delphi中来个覆盖的小例子吧:

type

Tfather=class //我们定义一个父类

public

function throwhand:string; virtual;

end;

type

Tson=class(Tfather) //我们定义一个继承父类的子类

public

function throwhand:string;override;

end;

//这是两个函数的实现:

{ Tfather }

function Tfather.throwhand: string;

begin Form1.edit1.Text:='right'; end;

{ Tson }

function Tson.throwhand: string;

begin Form1.edit2.Text:='left'; end;

//这是对函数的调用:

procedure TForm1.Button1Click(Sender: TObject);

var FatherUse:Tfather; SonUse:Tson;

begin

FatherUse:=Tfather.Create;

SonUse:=Tson.Create;

FatherUse.throwhand;

SonUse.throwhand;

FatherUse.Free;

SonUse.Free;

end;

这是效果图:

我们看到,父类被一个叫virtual的关键字所修饰。这是何故?不加行吗?当然不行,原因就是前面所述,Delphi的方法都是静态的。我们知道,Java中,被修饰成abstract 或final的方法是不能被覆盖的。由此可知,Delphi的默认的静态方法也不能被覆盖。因此,Delphi定义了两个关键字:virtual(虚拟)和dynamic(动态)。它们让函数和过程成为动态的,用于后关联。Virtual和dynamic作用大致相同。只是virtual的方法较dynamic的方法在VMT中占用空间较大,而执行时间较短。这是因为,子类在override父类中的某一个virtual方法时,VMT会为子类提供未被voerride的其它父类的virtual方法。而dynamic则只提供被override的方法。这两个方式个有好处,在Delphi中常被一起使用。

嗯,再多想想。如果父类的一个virtual方法不但要被子类方法override,还要被同一个类中的同名方法overload,那要怎么做呢?看看下面的例子:

type

Tfather=class

public //多了关键字overload

function throwhand:string; overload;virtual;

function throwhand(m:integer):integer; overload;virtual;

end;

type

Tson=class(Tfather)

public //多了关键字reintroduce,我发现不用它也行。但建议使用。

function throwhand:string;reintroduce;override;

end;

我们再来看看实现部分:

{ Tfather }

function Tfather.throwhand: string;

begin

result:='right';

end;

function Tfather.throwhand(m: integer): integer;

begin

result:=m;

end;

{ Tson }

function Tson.throwhand: string;

begin

Form1.edit2.Text:='left';

end;

这是调用部分:

procedure TForm1.Button1Click(Sender: TObject);

var

FatherUse:Tfather;

SonUse:Tson;

begin

FatherUse:=Tfather.Create;

SonUse:=Tson.Create;

Form1.edit1.Text:='usehand:'+FatherUse.throwhand+'throwfar:'+inttostr(FatherUse.throwhand(500))+'m';

SonUse.throwhand;

FatherUse.Free;

SonUse.Free;

end;

好了,Delphi的覆盖就聊到这里,嘻嘻,该来杯咖啡享受一下了。下面是Java的覆盖,它可没有那么多关键字。

这是Do.java文件的代码:

class A{ //这是父类

void throwhand(){

System.out.println("right!");

}

}

class SA extends A{ //这是子类

void throwhand(){

System.out.print("left!");

}

}

public class Do{

public static void main(String[] args){

A a=new A(); //父类实例化;

SA s=new SA(); //子类实例化;

System.out.println("-------------------------");

System.out.print("Father throwhand is: ");

a.throwhand(); //调用

System.out.println(" ");

System.out.print("Son throwhand is: ");

s.throwhand(); //调用

}

}

这是效果图:

到此,我对多态的gab就该结束了。希望你至少没有被我的文字弄烦。如果你真的烦了,那后面的系列文章,哎,不看也罢。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝網路 版權所有