第二章-Delphi面向对象的编程方法(四)(3)

2.2.6 对象变量的赋值 

如果两个变量类型相同或兼容,您可以把其中一个对象变量赋给另一个对象变量。例如,对象TForm1和TForm2都是从TForm继承下来的类型,而且Form1和Form2已被说明过,那么您可以把Form1赋给Form2:

Form2 :=Form1;

只要赋值的对象变量是被赋值的对象变量的祖先类型,您就可以将一个对象变量赋给另一个对象变量。例如,下面是一个TDataForm的类型说明,在变量说明部分一共说明了两个变量:AForm和DataForm。 

type

TDataForm = class(TForm)

Button1:TButton;

Edit1:TEdit;

DataGrid1:TDataGrid;

Database1:TDatabase;

TableSet1:TTableSet;

VisibleSession1:TVisibleSession;

private

{私有域说明}

public

{公有域说明}

end;

var

AForm:TForm;

DataForm:TDataForm;

因为TDataForm是TForm类型的后代,所以Dataform是AForm的后代,因此下面的赋值语句是合法的:

AForm :=DataForm;

这一点在Delphi中是极为重要的。让我们来看一下应用程序调用事件处理过程的过程,下面是一个按钮部件的OnClick事件处理过程:

procedure TForm1.Button1Click(Sender:TObject);

begin

end;

您可以看到TObject类在Delphi的Visual Component Library的顶部,这就意味着所有的Delphi对象都是TObject的后代。因为Sender是TObject类型,所以任何对象都可以赋值给它。虽然您没有看见赋值的程序代码,但事实上发生事件的部件或控制部件已经赋给Sender了,这就是说Sender的值是响应发生事件的部件或控制部件的。

您可以使用保留字is来测试Sender以便找到调用这个事件处理过程的部件或控制部件的类型。Delphi中的一个显示drag-and-drop的DRAGDROP.DPR工程。加载它,可以查阅到DROPFONT.PAS库单元的代码,在Memo1DragOver方法中检查了一个对象变量的类型。在这种情形下,参数是Source而不是Sender。 

procrdure TForm1.Memo1DragOver(SenderSource:TObject;X,Y:integer;

State:TDragState;var Accept:Boolean);

begin

Accept :=Source is TLabel;

end;  

Source参数也是TObject类型,Source被赋值为那个被拖曳的对象。用Memo1DragOver方法的目的是确保只有标签可以被拖曳。Accept是布尔型参数,如果Accept为True,那么用户选择的部件可以被拖曳;反之当Accept的值为False时,用户就不可以拖曳选择控制部件。is保留字检查Source是否TLabel的类型,所以Accept只有在用户拖曳一个标签时才为真,并作为变参输出到函数之外。

下面的drag-and-drop展示的Memo1DragDrop事件处理过程中也使用了Source参数。这个方法是为了把Memo部件的字型改变成和放入这个备注控制部件的标签一样的字型: 

procedure TForm1.Memo1DragDrop(SenderSource:TObject;

X,Y:Integer);

begin

Memo1.Font := (Source as TLabel).Font;

end; 

当您在这个事件处理过程中编写赋值语句时,开发人员并不知道用户会放入哪一个标签,只有通过参考这个标签的名称(Source as TLabel)用户才能知道,并把标签类型赋给Memo1.TFont。Source包含了用户拖放控制部件的名称,只有当Source是一个标签时,这个事件处理过程才允许这个赋值发生。

2.2.7 建立非可视化对象 

您在Delphi中使用的大部分对象都是您在设计和运行期间可以看见的部件,例如编辑框、按钮等;一些部件,如通用对话框(Common dialog box)等,在设计时看不见,而在运行时可以看见;另外有些部件,例如计时器(Timer)、数据源(Data Source)部件等,在程序的运行期间没有任何可视化的显示,但您却可以在您的应用程序中使用它们。 

2.2.7.1说明一个非可视化对象 

下面,通过一个简单的例子讲述如何建立自己的非可视化对象:

您可以用如下的方法,建立一个自己的TEmployee非可视化对象: 

type

Temployee = class(TObject);

Name := String[25];

Title := String[25];

HourlyPayRate : Double;

function CalculatePayAmount:Double;

end; 

在这种情况下,TEmployee从TObject继承下来,且包含三个域和一个方法。把您建立的类型说明放在库单元中的说明部分,并和窗体说明放在一起。在这个程序库单元的变量说明部分,说明一个新类型的变量: 

var

Employee : TEmployee; 

2.2.7.2用Create方法建立对象实例 

TEmployee只是一个对象类型。除非通过一个构造函数的调用从而被实例取代或创建,否则一个对象并不存储在内存中。构造函数是一个方法,它为新对象配置内存并且指向这个新的对象。这个新的对象也被称为这个对象类型的一个实例。

建立一个对象的实例,需要调用Create方法,然后构造函数把这个实例赋给一个变量。如果您想说明一个TEmployee类型的实例,在您访问这个对象的任何域之前,您的程序代码必须调用Create。

Employee := TEmployee.Create; 

Create方法并没有在TEmployee类型中说明,它继承自TObject类型。因为TEmployee是TObject的子类,所以它可以调用Create方法而创建一个TEmployee实例。然后把它赋给Employee变量。在创建了一个这样的对象后,您就可以象使用其他的Delphi对象一样访问Employee对象了。 

2.2.7.3 撤销对象 

当您使用完对象后,您应该及时撤销它,以便把这个对象占用的内存释放出来。您可以通过调用一个注销方法来撤销您的对象,它会释放分配给这个对象的内存。

Delphi的注销方法有两个:Destroy和Free。Delphi建议使用Free,因为它比Destroy更为安全,同时调用Free会生成效率更高的代码。

您可以用下列的语句释放用完的Employee对象: 

Employee.Free; 

和Create方法一样,Free方法也是TEmployee从TObject中继承过来的。把您的注销放在try…finally程序模块的finally部分,而把对象的程序代码放在try部分是编程的好习惯。这样,即使您的程序代码在使用对象时发生了异常事件,也会确保您为这个对象分配的内存会被释放。关于异常处理和try…finally程序模块的信息以及建立非可视化对象的例子,在后文中还将仔细讲述。

时间: 2025-01-30 10:31:33

第二章-Delphi面向对象的编程方法(四)(3)的相关文章

第二章-Delphi面向对象的编程方法(四)(1)

2.1.10.7 将库单元加入工程 将库单元加入工程是比较简单的.无论是您自己建立的库单元还是Delphi建立的与窗体有关的库单元,如果已经完成,则先打开您想加入库单元的工程(可以用Open Project打开工程):再选用File|Open File,然后选择您想加入的源程序(.PAS文件),并选择OK即可.则库单元被加入到应用程序中. 2.2 用Delphi的对象进行编程 Delphi是基于面向对象编程的先进开发环境.面向对象的程序设计(OOP)是结构化语言的自然延伸.OOP的先进编程方法,

第二章-Delphi面向对象的编程方法(三)(2)

2.1.9.4 字符串类型 字符串类型事实上是一个一维的字符数组.当您说明一个字符串型的变量时,您应当指明这个字符串的大小,下面是说明字符串类型的例子: type MyString: string[15]; var MyName: MyString; 则变量MyName被说明成为最多可以包含15个字符.如果您没有说明字符串的大小,Delphi会认为字符串包含最大值255个字符.给字符串赋值可以直接使用单引号括起的字串赋值: MyName := 'Frank.Smith'; 或MyName :=

第二章-Delphi面向对象的编程方法(四)(2)

当您使用Object Inspector来改变对象(部件)的名称时,这个名称的改变会反映到程序中.例如,在Object Inspector中将Form1的Name属性命名为ColorBox,您会发现在类型说明部分,会将前文的TForm1改为: TColorBox=class(TForm); 并且在变量说明部分,会说明ColorBox为TColorBox类型的变量,由Delphi自动产生的事件处理过程名称会自动改为TColorBox.Button1Click:但您自行编写的实现部分的代码却不会被自

第二章-Delphi面向对象的编程方法(一)(1)

Delphi的编程语言是以Pascal为基础的.Pascal语言具有可读性好.编写容易的特点,这使得它很适合作为基础的开发语言.同时,使用编译器创建的应用程序只生成单个可执行文件(.EXE),正是这种结合,使得Pascal成为Delphi这种先进开发环境的编程语言. 本章中,我们将讨论Object Pascal的主要特点,并讲解如何在事件处理过程和其他应用程序中,使用它来编制程序代码.本章将讲解Delphi应用程序中最常用的Object Pascal语法,而不是Pascal语言的一切细节.如果您

第二章-Delphi面向对象的编程方法(二)(2)

2.1.7 关于作用范围 2.1.7.1 标识符的作用范围 一个变量.常量.方法.类型或其他标识符的范围定义了这个标识符的活动区域.对于说明这个标识符的最小程序模块而言,此标识符是局部的.当您的应用程序在说明一个标识符的程序模块外执行时,该标识符就不在此范围内.这意味着此时执行的程序无法访问这个标识符,只有当程序再度进入说明这个标识符的程序模块时,才可以访问它. 下面的示意图表示一个含有两个库单元的工程,每个库单元中又各有三个过程或事件处理过程. 2.1.7.2 访问其他程序模块中的说明 您可以

第二章-Delphi面向对象的编程方法(二)(1)

2.1.4 跳转语句 Object Pascal的跳转语句有if和case两个. 2.1.4.1 if语句 if语句会计算一个表达式,并根据计算结果决定程序流程.在上文的例程中,根据ColorDialog.Execute的返回值,决定窗体的背景颜色.if保留字后跟随一个生成Boolean值True或False的表达式.一般用"="作为关系运算符,比较产生一个布尔型值.当表达式为True时,执行then后的语句.否则执行else后的代码,if语句也可以不含else部分,表达式为False

第二章-Delphi面向对象的编程方法(一)(2)

2.1.2.3 常量 常量在说明时就被赋予了一个值,在程序执行过程中是不可改变的.下面的例子说明了三个常量: const Pi = 3.14159; Answer = 342; ProductName = "Delphi"; 象变量一样,常量也有类型.不同的是,常量假设其类型就是常量说明中其所代表的值的类型.上文的三个常量的类型分别是real型.整形.字符串型.常量用"= " 表示两边的值是相等的. 2.1.3 过程与函数 过程与函数是程序中执行特定工作的模块化部分

第二章-Delphi面向对象的编程方法(三)(1)

2.1.8.4 过程和函数的语句部分 过程或函数的语句部分由begin开始,end结束.函数需要一个返回值.可以将返回值赋给函数名称,也可以将返回值赋给Result变量.下面的例程将返回值赋给函数名称: function CalculateInterest(Principal,InterestRate: Double):Double; begin CalculateInterest := Principal * InterestRate; end; 将返回值赋给Result变量也是可以的,则上面

第五章-Delphi图形图像编程(一)(1)

在Delphi中,专门定义了一组对象和部件用以绘制图形,完成一些简单的图像功能.利用这些对象.部件的方法,可以方便地绘制各种常用图形:通过设置它们的属性,能得到不同风格的图形.另外,通过对鼠标事件的定义,可以方便的设计图形绘制程序. 本章将介绍以下内容: 1. TCanvas,TPen,TBrush,TColor对象的方法及属性: 2. 绘图功能的实现: 3. TImage,TPicture,TBitBtn,TBitmap部件的方法及属性: 4. 图像观测及处理. Graphex.dpr是一个简