分享
 
 
 

Delphi中的类和对象

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

谈谈Delphi中的类和对象

1.登不了大雅之堂地理解几个概念

说到类和对象,我们不能不提及这样几个概念:类,对象,实例。就我个人觉得可

以这样来理解:对象指的是泛称,自然界的任何实体都可以看成一个对象;而类则是

以这些对象某些特征而分成的一系列的种类;实例则是特指属于某一个类的一个对象。

好啦,这些大道理我就不用多说了。不如来一个“背道而驰”的作法,我们用Delphi

code 来阐述这些外国人提出的一些令我们中国人不好理解的概念吧:

var

ABtn:TButton;

义ABtn是属于TButton类的一个对象,但ABtn不能说是一个实例,因为它还没有

创建,所以我们说这是定义了一个对象,如果说定义了一个实例,多多少少有

些不够确切。:)

begin

ABtn:=TButton.Create(Self);//创建一个TButton的实例

ABtn.Caption:='对象';

ABtn.Free;

end;

2.对象是一个地地道道的指针

从物理角度来看,对象就是一段地址空间,这段地址空间的标志就是我们定义的

类“变量”。所以我们可以把对象看成一个类的指针。大家知道,要访问一个指针就

必须对指针初始化。对象的既然是一个指针,也必须对它进行初始化。如何初始化呢?

还是说指针的初始化吧。对于一个指针可以有以下两种方法来进行初始化:

(一)直接分配

var

Pint:^Integer;

begin

new(Pint);

Pint^:=12;

Dispose(Pint);

end;

(二)指向别的已分配空间的变量

var

Pint:^Integer;

i:integer;

begin

i:=12;

Pint:=@i;

end;

有趣的是,对象这种“指针”也有两种方法初始化

(一)直接分配

var

AForm:TForm;

begin

AForm:=TForm.Create(Self);

AForm.ShowModal;

AForm.Free;

end;

(二)指向别的已分配空间的实例

var

AForm:TForm;

begin

AForm:=Self;

AForm.Caption:='知道了吗?为什么会这样呢';

end;

file://这个AForm和它所指向的Form实例共用同一段地址单元,所有对AForm操作都将反应

file://到它所对应的Form实例之上。

说到这,我们就很好解释为什么过程(函数)的对象参数传递时,象这样这的格式:

(一)procedure SetEdit(var Edit:TEdit);

begin

Edit.Text:='11';

end;

(二)procedure SetEdit(Edit:TEdit);

begin

Edit.Text:='11';

end;

效果是一样的了。(一)是把一个TEdit实体作为参数引用的形式进行参数传递,(二)是

把一个TEdit的对象“指针”作为参数传递。

3.类可以理解成一种特殊的数据类型

我们知道数据类型可以进行强制类型转化,类即然可以理解成一种数据类型,那

么它也应该可以进行类类型转。比方如下代码为一个按钮(Button1)的单击事件:

(一)

procedure TForm1.Button1Click(Sender: TObject);

var

ACaption:String;

begin

ACaption:=TButton(Sender).Caption;//Sender从TObject转化到TButton

ShowMessage(Format('You clicked ''%s'' !',[ACaption]));

end;

在这段代码中,Sender是一个TObject型对象,我们把它强制转化为TButton类型。如你

看得不清楚,可以参照一下我们通常的数据类型的转化:

(二)

procedure TForm1.Button1Click(Sender: TObject);

var

S_Str:String;

P_Str:PChar;

begin

S_Str:='I love China!';

P_Str:=PChar(S_Str);

S_Str:='';

S_Str:=String(P_Str);

ShowMessage(S_Str);

end;

但是在面对对象的程序设计过程中,强调的是安全性,如(一)的强制类型转化存在着不

安全性。如下的代码,依然是写Button1.OnClick事件:

(三)

procedure TForm1.Button1Click(Sender: TObject);

begin

TCanvas(Sender).Brush.Color:=clRed;

end;

执行一下,就会出错。这样岂不是违背了面对对象的程序设计的宗旨了吗?没有,即然

是类,就应该有类特定的类强制转化方法,改(三)的方法如下:

(四)

procedure TForm1.Button1Click(Sender: TObject);

begin

(Sender as TCanvas).Brush.Color:=clRed;

end;//用as来转化,as就可以把错误抓住,不会影响程序的正常运行。

说到这我顺便提一下VB吧,如果学过VB的人可能觉得其中的控件数组比较爽,尤其是在

编写象计算器这样的程序时。但Delphi给我们什么呢?答案是Delphi也能快速简洁的开

发出这样的程序。如是操作:在窗体上放一个Edit和十个Button,把Button.Caption分

别设为'0','1','2',...'9',然后写一个按钮的OnClick事件如下:

(五)

procedure TForm1.Button1Click(Sender: TObject);

begin

Edit1.Text:=Edit1.Text+(Sender as TButton).Caption;

end;

把别的Button的OnClick事件都关联到Button1Click上,运行程序。拍拍手!这样计算器

程序的雏形就具备了。我们用Delphi的类类型转化,开发出来类似VB中的控件数组功能

的程序也是很棒的嘛!:)

4.抽象类和它的实例

Delphi中有一种类为抽象类,你不能天真的直接为它创建一个实例。如:TStrings

类。如下代码:

(一)

var

StrLst:TStrings;

begin

StrLst:=TStrings.Create;

StrLst.Add('I love Japan!');

StrLst.Free;

end;

这是不对的。那如何为诸如TStrings这样的抽象类构造实例呢?答案是借助它的非抽

象子类。我们知道TStrings有一个TStringList非抽象子类。我们就可以这样作:

(二)

var

StrLst:TStrings;

begin

StrLst:=TStringList.Create;//借助其子类的构造器,对StrLst进行子类化

StrLst.Add('I love China!');

StrLst.Free;

end;

(三)

var

StrLst:TStringList;

begin

StrLst:=TStringList.Create;

file://放弃吧,不要再用抽象类,完全用它的“儿子”来你的事吧

StrLst.Add('I love China!');

StrLst.Free;

end;

5.类是一种对数据和操作高度的封装机制

(一)数据封装

unit Unit2;

interface

type

TEmployee=class

private

FName:String;

public

Constructor Create;

function GetName:String;

procedure SetName(AName:String);

end;

implementation

{ TEmployee }

constructor TEmployee.Create;

begin

FName:='BlazingFire';

end;

function TEmployee.GetName: String;

begin

Result:=FName;

end;

procedure TEmployee.SetName(AName: String);

begin

FName:=AName;

end;

end.

如上代码,我们就用了一个过程SetName和一个函数GetName对私有变量FName进行完全的

封装。我们要对FName操作就只有这样:

uses

unit2;

procedure TForm1.Button1Click(Sender: TObject);

var

AEmployee:TEmployee;

begin

AEmployee:=TEmployee.Create;

AEmployee.SetName('Rose');//利用SetName来设置FName

MessageBox(Handle,PChar(AEmployee.GetName),'Empoyee',0);

file://用GetName来访问FName

AEmployee.Free;

end;

(二)操作封装

unit Unit2;

interface

type

TDivision=Class

public

file://多态性让你的程序更据有“柔韧性”

function GetDiv(Num1,Num2:Double):Double;overload;

function GetDiv(Num1,Num2:integer):integer;overload;

end;

implementation

{ Division }

function TDivision.GetDiv(Num1, Num2: Double): Double;

begin

try

Result:=Num1/Num2;

except

Result:=0;//提供弹形处理机制,处理除数为0情况

end;

end;

function TDivision.GetDiv(Num1, Num2: integer): integer;

begin

try

Result:=Num1 div Num2;

except

Result:=0;//提供弹形处理机制,处理除数为0情况

end;

end;

end.

如上代码我们通过类的多态性机制把除法分别处理成整除和非整除,又通过异常处理屏

去除数为0的情况,从而保证操作的安全性,在调用时,我们就可以这样来:

uses

unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);

var

Division:TDivision;

IValue:integer;

FValue:Double;

begin

Division:=TDivision.Create;

IValue:=Division.GetDiv(1,2);

FValue:=Division.GetDiv(1.0,2);

IValue:=Division.GetDiv(1,0);

FValue:=Division.GetDiv(1.0,0);

Division.Free;

end;

6.类是一种代码重用机制

比方在5中我们想对这个类加上一个GetAdd函数来作加法运算就可以用类的继承。如

下写就可以了:

(一)

unit Unit2;

interface

type

TDivision=Class

public

function GetDiv(Num1,Num2:Double):Double;overload;

function GetDiv(Num1,Num2:integer):integer;overload;

end;

type

TOperation=Class(TDivision)

public

function GetAdd(Num1,Num2:Double):Double;

end;

implementation

{ Division }

function TDivision.GetDiv(Num1, Num2: Double): Double;

begin

try

Result:=Num1/Num2;

except

Result:=0;

end;

end;

function TDivision.GetDiv(Num1, Num2: integer): integer;

begin

try

Result:=Num1 div Num2;

except

Result:=0;

end;

end;

{ TOperation }

function TOperation.GetAdd(Num1, Num2: Double): Double;

begin

Result:=Num1+Num2;

end;

end.

这里我们从TDivision继承了一个子类TOperation。TOperation就可以即有TDivsion

公有方法GetDiv,又有自己的独特的方法GetAdd。这是类为我们提供的“鱼和熊掌兼

得”之法。不错吧。:)

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