本章要点:
枚举类型的定义及使用
子界类型的定义及使用
集合类型的定义及使用
记录类型的定义及使用
面向对象程序设计第 6章 自定义类型
6.1 枚举类型
Object Pascal有五种标准数据类型:整型( Integer)、实型
( Real)、字符型( Character)、字符串型( String)和布尔型
( Boolean)。这些数据类型无需声明,即可在程序中直接使用。为了满足用户的需要,Object Pascal还允许用户使用自定义的数据类型。自定义的数据类型,属于高级数据类型。
Object Pascal高级数据类型在使用之前必须首先使用类型定义语句进行定义。经过定义后的高级数据类型就可在程序代码中使用。其用法与常用的整型、字符串型用法相同。
常用的高级数据类型有枚举类型、子界类型、集合类型及记录类型。
6.1.1 枚举类型的定义在处理实际问题过程中常用到的数据取值可能总是有限的几个值,
例如学生成绩等级有优秀、良好、及格、不及格;处理这一类数据时可以用数值或字符串来表示,比如用,1”表示优秀,,2”表示良好。利用数值表示此类数据不直观,容易出错,利用字符串表示不方便处理,
占用内存较多。为此,Object Pascal提供了枚举类型用于处理这一类数据。
6.1.1 枚举类型的定义枚举类型的定义格式如下:
type
<枚举类型名称 >=(<标识符 1>,<标识符 2>,…,<标识符 n>);
<枚举类型名称 >是用户自定义的枚举类型的名称。 <标识符 >表示该类型数据中的元素,圆括号中列出了该类型数据的所有取值,这些取值又称为枚举常量。每个枚举常量必须是标识符,不能是其他任何数据类型。枚举常量不允许在同一数据类型定义中重复出现,也不允许同时在不同的枚举类型定义中出现。
例如可以定义一个 Color枚举类型:
type
color=(Red,Yellow,Blue,White,Black);
该枚举类型名为 color,其中包括五个枚举常量,Red,Yellow、
Blue,White,Black。
枚举类型变量的声明与其他类型变量的声明完全相同。如下面的代码声明了一个枚举类型 color的变量 c1,c2:
var c1,c2,color;
声明了一个枚举类型变量后可以给它赋值,但必须注意的是只能将枚举类型中定义的枚举常量赋值给它,
则会出现错误。
6.1.2 枚举类型的运算 (1)
从本质上分析,枚举类型实际上就是一个数据取值结果的集合 。 用枚举常量表示使程序可理解性加强,但与集合不同的是每个枚举常量对应一个序数 ( 整数 ),利用序数可以方便地对枚举类型数据进行计算 。
1,使用序数函数
Object Pascal规定,在枚举类型定义语句中的每一个枚举常量都与唯一的一个序数相对应。对于一个有 n个枚举常量的枚举类型,其中的枚举常量从左到右依次对应序数为 0~ n-1。使用序数函数 Ord可以得到每个枚举常量所对应的序数,使用前趋函数 Pred()返回数据的前趋值,使用后继函数 Succ()返回数据的后继值,使用首序数函数 Low()返回序数类型的数据中序数最小的一个数据,使用末序数函数 High()返回序数类型的数据中序数最大的一个数据。
0 1 2 3 4
6.1.2 枚举类型的运算 (2)
type
color=(Red,
Yellow,Blue,White,Black);
0 1 2 3 4
在下面的定义中:
枚举常量的序数依次为 0~ 4,Ord(Red)的值为 0,Pred(Blue)的值为 Yellow,
Succ(Blue) 的值为 White,Low(Color) 的值为 Red,High(Color) 的值为 Black。
注意,不要对第一个序数的求前趋和对最后一个序数求后继。
2,关系运算由于每个枚举常量对应唯一一个序数,因此可以在枚举常量之间进行比较。
比较规则是:按枚举值的序数进行比较,序数大者较大。对应上述 Color类型定义中,Blue>Yellow的值为 True。
6.1.3 枚举类型的使用 (1)
( 1)对各枚举常量按常量进行处理,不能对它们进行赋值,也不能再把它定义为其他类型的变量。
( 2)定义了一个枚举类型的变量后,可以将枚举常量赋值给该变量,
不能将枚举常量之外的任何值赋予该枚举变量,也不能利用序数来赋值。
( 3)可以指定枚举常量的序数。缺省情况下,枚举值的序号从 0开始,
并且接下来的序列对应类型声明中相应的标识符。可以通过对部分或全部枚举值明确指定序号来忽略缺省序号。
枚举类型在定义后方可在程序中使用,枚举类型的使用与基本数据类型有相似之处,但对枚举类型的使用有以下几点说明 。
【 例 6-1】 口袋中有红、黄、蓝、黑、白五种颜色的小球若干(各种颜色小球数大于 1),每次从口袋中依次取出三个小球,利用枚举类型编写程序,
求出取得三种不同颜色小球的可能取法。
6.1.3 枚举类型的使用 (2)
分析:该程序要用到枚举类型,在编程中可以声明一个包括五种颜色的枚举类型 。 从若干小球中取三个小球,三个小球的颜色可能分别是五种颜色中的一种,而且取得三个小球的颜色不同,各种可能取法可以利用循环语句实现,直到取得三种颜色不同的小球 。 对于各种取法要用字符串的形式显示出来,所以可以编写一个枚举类型转换为字符串类型的子程序 。
启动 Delphi 7.0,新建一个工程,在窗体中添加一个标签、一个列表框和一个按钮,设置标签的标题属性 (Caption)为“红、黄、蓝、黑、白五个五种颜色的小球,取三个小球可能取法:”,设置按钮的标题属性
(Caption)为“列举”。
在实现部分关键字 Implementation之后声明枚举类型,然后声明一个 枚举类型转换为字符串的函数,代码如下:
implementation
{$R *.dfm}
type
ball=(Red,Yellow,Blue,White,Black); //声明枚举类型
6.1.3 枚举类型的使用 (3)
function balltostr(oneball:ball):string; //枚举类型变量转换为字符串
begin
case oneball of
Red,result:='Red';
Yellow,result:='Yellow';
Blue,result:='Blue';
White,result:='White';
Black,result:='Black';
end;
end;
单击“列举”按钮,运行结果如图 6-1所示。
图 6-1 列举不同颜色小球的可能取法
6.2 子界类型在实际应用中,许多变量的取值都有一定范围的限制,如学生学习成绩在 0~ 100之间,月份的取值在 1~ 12之间 。 在这种情况下,数据的取值是某个数据类型取值的一部分,在 Object Pascal 中这种具有确定范围的数据类型称为基类型,且取值范围确定的数据可定义为,子界类型,,其中基类型必须为顺序类型 。
6.2.1 子界类型的定义子界类型的定义格式如下:
type
<子界类型名称 >=<常量 1>…< 常量 2>;
<子界类型名称 >是用户定义的子界类型的名称。 <常量 1>表示子界类型的下界,< 常量 2>表示子界类型的上界,子界类型的上下界必须属于相同的顺序类型。
注意,Object Pascal子界类型的下界必须小于上界。
6.2.2 子界类型的使用( 1)
子界类型的运算与其基类型所允许的运算完全一致,如基类型为整型的子界变量可以进行算术,关系等运算 。
启动 Delphi 7.0,新建一个工程,在窗体中添加一个按钮、两个编辑框和三个标签,将按钮的标题属性( Caption)设置为判断,将标签的标题属性
( Caption)分别设置为“年”、“月”、,”,将两个编辑框的文本属性
( Text)设置为,2000”和,1”。
双击按钮,添加事件代码如下:
procedure TForm1.Button1Click(Sender,TObject);
var
year:1..3000;
month:1..12;
days:28..31;
【 例 6-2】 编写一个程序,输入年份月份,输出该月有多少天。
分析:年份、月份的取值范围都是有限的,可以将它们声明为子界类型。根据年份可以判断是否闰年,然后从一月至十二月依次判断天数。
6.2.2 子界类型的使用( 2)
begin
year:=strtoint(edit1.Text );
month:=strtoint(edit2.Text );
case month of
1,3,5,7,8,10,12:days:=31;
4,6,9,11,days:=30;
2,if ((year mod 4=0)and(year mod 100<>0))
or (year mod 400=0) then days:=29
else days:=28 //判断是否闰年输出二月份天数
end;
label3.Caption,='该月天数为 '+inttostr(days);
end;
输入年份、月份,单击按钮,执行结果如图 6-2所示 。
图 6-2 输出该月份的天数
6.3 集合类型
6.3.1 集合类型的定义集合是指具有相同性质且可以相互区分的对象的全体 。 例如,所有的英文字母可以组成一个集合,全体自然数组成一个集合,某个学校的全体学生组成一个集合,等等 。 为了表示集合,Object Pascal 引入了集合类型 。
使用集合类型和集合变量之前必须首先进行类型定义和变量声明。
1,集合与集合类型集合的特点是所包括的各个对象具有某种相同的性质,构成集合的各个对象称为集合的元素,集合的元素是某种简单数据类型的值,这种数据类型称为集合的“基类型”,基类型只能是顺序类型。对于集合有以下几个特点:
( 1)集合中的元素是互异的,即相同的元素视为同一个元素,集合 {1,
2,2}与集合 {1,2}是相同的;
( 2)集合中的元素是无序的,{1,2}与 {2,1}是同一个集合;
6.3.1 集合类型的定义 (1)
2,集合定义集合的声明格式如下:
Type
<集合类型名称 >=Set of <基类型 >;
<集合类型名称 >是用户定义的集合类型名称。 <基类型 >表示集合中各元素的类型,可以是字符型、布尔型、枚举型和子界型等顺序类型,
但不能是整型、实型和其他的构造类型。
( 3)集合中的元素按顺序出现时可以写为子界的形式,如 [6,7,8,9,11,
13]可写为 [6…9,11,13];
( 4)一般意义上的集合元素个数可以是有限的,也可以是无限的,但在
Object Pascal中处理的都是含有有限个元素的集合;
( 5)元素与集合的关系是“属于”或“不属于”关系。
集合类型属于构造类型,是由其他的数据类型按照一定的规则构造而成的。 Object Pascal规定集合的基类型可能的值不能超过 256个,且序号必须在
0到 255之间,这同时也表明,集合中元素的个数最多是 256个。
6.3.1 集合类型的定义 (2)
若基类型为枚举或子界类型,则必须先定义该类型,再定义集合类型。例如:
type
Colors=(Red,Blue,Yellow,White,Black);
color=set of Colors;
numbers=set of 1..10;
基类型不能含有多于 256个可能的值,基类型的序号也必须在 0到
255之间。由于整数类型的取值可能超过了规定值 256范围,所以不能用整数类型作为基类型。但基类型可以是整型的子界类型。由于基类型的尺寸局限,集合类型通常用子界类型来定义,且该子界类型的元素个数不能超过 256。
例如,以下定义会显示编译错误:
type
intset = set of 1..300;
6.3.1 集合类型的定义 (3)
3,集合变量定义了一个集合则可以声明集合变量,集合变量声明的格式如下:
var <变量名 >,<集合类型名称 >;
集合变量的取值称为集合值,它是基类型元素的一个集合,取值范围是包括空集合在内的全体子集。集合值的一般表示格式为方括号括起来的元素序列,
元素之间用逗号隔开。
[<元素 1>,<元素 2>,…,< 元素 n>,]
如下定义了一个集合变量:
Type
Colors=(Red,Yellow,Blue);
BasicColor=set of Colors;
var Color1:BasicColor;
则集合变量 Color1的取值可以是下列所示的任何集合:
[],[Red],[Yellow],[Blue],[Red,Yellow],[Red,Blue],[Yellow,Blue],
[Red,Yellow,Blue]
若集合类型的基类型有 n个元素,根据组合可知该类型变量的取值有 2n个,
其中包括一个空集合 [ ]。
6.3.2 集合类型的运算 (1)
1,集合的并、交、差运算相同类型的集合可以进行并、交、差运算,其值仍是一个该类型的集合。
并运算:集合 A,B类型相同,则 A和 B的并运算记作 A+B或 B+A,计算结果是由 A和 B中所有不重复元素组成的集合。
交运算:集合 A,B类型相同,则 A和 B的交运算记作 A* B或 B* A,计算结果是由 A和 B中所有公共元素组成的集合。
差运算:集合 A,B类型相同,则 A和 B的差运算记作 A-B,计算结果是由所有属于集合 A而不属于集合 B的元素组成的集合。利用差运算可以删除集合中的一些元素。
例如,A=[1,2,3],B=[2,3,4],则:
A+B=[1,2,3,4];
A*B=[2,3];
A-B=[1];
B-A=[4];
集合类型数据的运算包括两大类,一类是集合的并,交,差运算,其运算结果仍为集合类型值;一类是集合的关系运算,其运算结果是布尔类型值 。
6.3.2 集合类型的运算 (2)
2,集合的关系运算集合的关系运算包括类型相同集合之间所进行的相等,=”、不等
,<>”、包含,>=”、被包含,<=”等运算,以及数据是否属于集合的 IN运算。这些运算的结果均为布尔类型值。
集合相等运算:如果相同类型集合 A和 B的元素完全相同,则运算
A=B或 B=A的值为 True,否则为 Flase。
[2,3]=[3,2]的值为 True。
集合的不等运算:如果相同类型集合 A和 B的元素不完全相同,则运算 A<>B或 B<>A的值为 True,否则为 Flase。
[2,3]<>[1,3,2]的值为 True。
集合的包含运算:如果集合 B中的元素都是集合 A中的元素,则运算
>=B(称为 A包含 B)的值为 True,否则为 Flase。
[1,3,2]>=[2,3] 的值为 True。
集合的被包含运算:如果集合 B中的元素都是集合 A中的元素,则运算 B<=A(称为 B被包含在 A中)的值为 True,否则为 Flase。
[RED,BLUE]<=[RED,GREEN,BLUE]的值为 True。
属于运算:如果数据 X与集合 A的基类型相同,且被包含在 A中,则运算 X
INA(称为 X属于 A)的值为 True,否则为 Flase。 RED IN [RED,BLUE] 的值为
True。
6.3.2 集合类型的运算 (3)
3,集合运算符的优先级集合运算符的优先级决定运算时的顺序,运算符的优先顺序如表 6-1所示。
优先顺序 运算符
1(最高) *(交运算)
2 +(并运算),-(差运算)
3(最低) =(相等),<>(不等),>=(包含)
<=(被包含),IN(属于)
表 6-1 集合运算符的优先级当一个表达式中含有多个集合运算符时,将按优先级由高到低的顺序求值。
6.3.3 集合类型的使用 (1)
集合有其自身特点,而且有单独的运算方法。在编程中可以根据需要灵活使用集合类型从而使问题简化。
【 例 6-3】 用集合数据类型求 1~ 100之间的所有素数。
分析:素数是大于 1且除了 1 和它本身外,不能被其他任何整数所整除的整数。对于求解 1~ 100之间的素数可以从 1到 100一一判断是否是素数,
然后输出素数。也可以采用筛选法,将 2~ 100之间的数看成一个集合,从中选出最小数,从中筛选去掉其所有倍数,再找出第二个数将其所有倍数从集合中筛选出去,……,一直增加到该数为集合中最大数的一半为止,
则将集合中所有是其他数的倍数的数全部选出,剩下的即为素数。
启动 Delphi 7.0,新建一个工程,在窗体中添加一个标签。
添加 Form1的 FormCreate事件代码如下:
procedure TForm1.FormCreate(Sender,TObject);
type
int100=2..100;
all=set of int100;
6.3.3 集合类型的使用 (2)
Var part:all; i,j:integer; str:string;
begin
part:=[2..100];
for i:=2 to 50 do //双重循环进行筛选
for j:=i+1 to 100 do
if (j mod i=0) then
part:=part-[j];
str:='';j:=0;
for i:=2 to 100 do //输出经筛选后剩下的素数
if i in part then
begin
j:=j+1;
str:=str+inttostr(i)+',';
if j mod 5=0 then
str:=str+chr(13);
end;
label1.Caption,=str;
end;
运行结果如图 6-3所示。
其中运用集合的差运算将不是素数的整数从集合中筛选出去。
图 6-3 列举 1~
100之间的所有素数
6.4 记录类型在解决现实问题中,常需要把一些数据类型不同的数据集中在一起,并作为一个整体处理。例如学生登记表一般包含学号、姓名、性别、年龄、家庭地址多条信息,每一个学生的情况可以看成一个整体,就像数据库中的一个记录一样。
6.4.1 记录类型的定义声明一个记录型的一般格式为:
Type
<记录类型名称 > =Record
<字段名 1>,<类型 1>;
<字段名 2>,<类型 2>;

<字段名 n>,<类型 n>;
end;
其中,记录类型名称必须是合法标识符,类型列表中的类型可以是任何已定义的类型,在同一记录类型中域名列表中的字段名不能相同,字段名也可以称为域名。
6.4.1 记录类型的定义以学生登记表为例,一般是由下列信息组成:学号、学生姓名、年龄、家庭地址。
以下程序声明了一个记录名为 student的记录类型:
Type
Student=record
StuId:integer;
Name:string[20];
Age:1..100;
Addr:string[40];
end;
该记录由四个字段组成,其中每个字段都有其确定的标识符和数据类型。记录的字段可以是任意数据类型,包括简单类型和构造类型,甚至可以是另一个已声明的记录类型。
声明了记录类型之后则可以声明相应类型的变量,声明记录类型变量的格式为:
var <变量名 >,<记录类型名称 >;
与声明整型、实型等基本类型的变量方法相同,下列程序声明了两个 student
类型的变量:
var student1,student2:student;
6.4.2 访问记录中的字段与 With语句 (1)
声明了一个记录后就可以对记录中各个字段进行访问,访问记录中的字段格式为:
<记录变量名 >.<字段名 >
可以对记录的单个字段进行访问,可以进行该字段所属数据类型的所有合法运算。也可以把记录作为一个整体,但只能进行赋值运算,即把一个同类型的一个记录整体赋值给另一个记录。
访问一个记录的多个字段时可以用 With语句简化,格式,
With <记录变量名 > do <语句 >
do后面可以是单条语句,也可以是复合语句(用 begin和 end括起来)。
在此语句中访问字段时不用再加记录变量名。
(具体例子见本教程 P90页 )
6.4.2 访问记录中的字段与 With语句 (2)
【 例 6-4】 利用记录类型编写一个计算学生总成绩的程序。每个学生记录由学号、姓名、语文、数学、英语五个字段组成。已知多个学生的各门课程成绩,计算总成绩。
分析:该程序首先用到记录类型,该记录类型包含五个字段:学号、
姓名、语文、数学、英语。根据题目要求要涉及多个记录,可以利用数组来实现对每个记录的处理。
图 6-4 利用记录实现对成绩的求和
启动 Delphi 7.0,新建一个工程,在窗体上添加六个标签( Label)、六个列表框 (ListBox)
和一个按钮 (Button),设置六个标签的标题
(Caption)属性分别为:,学号”、“姓名”、
“语文”、“数学”、“英语”、“总成绩”,
设置按钮的标题 (Caption)属性为“计算总成绩”,界面设计如图 6-4所示。
6.4.2 访问记录中的字段与 With语句 (3)
在程序实现( implementation)部分之后要对程序用到的记录类型、数组类型及用到的变量进行声明,代码如下:
implementation
{$R *.dfm}
type
student=record
StuId:string[8];
Name:string[20];
philology:1..100;
math:0..100;
english:0..100;
end;
stud=array[1..5] of student;
var
Form1,TForm1;
i:integer;
st:stud;
6.4.2 访问记录中的字段与 With语句 (4)
已知多个记录的值,程序运行中要显示已知记录的值,所以添加 TForm1的
FormCreate事件,使窗体的列表框中显示已知记录的各字段值,添加代码如下,
procedure TForm1.FormCreate(Sender,TObject);
begin
st[1].StuId,='20002316';st[1].Name,='王明 ';
st[1].philology,=87; st[1].math,=77;st[1].english,=82;
st[2].StuId,='20002318';st[2].Name,='孙刚 ';
st[2].philology,=68; st[2].math,=79;st[2].english,=74;
st[3].StuId,='20002325';st[3].Name,='赵小军 ';
st[3].philology,=90; st[3].math,=96;st[3].english,=73;
st[4].StuId,='20002330';st[4].Name,='李芳 ';
st[4].philology,=87; st[4].math,=80;st[4].english,=88;
st[5].StuId,='20002336';st[5].Name,='田兵 ';
st[5].philology,=75; st[5].math,=89;st[5].english,=71;
for i:=1 to 5 do
begin
listbox1.Items.Add(st[i].StuId );
6.4.2 访问记录中的字段与 With语句 (5)
listbox2.Items.Add(st[i].Name );
listbox3.Items.Add(inttostr(st[i].philology));
listbox4.Items.Add(inttostr(st[i].math) );
listbox5.Items.Add(inttostr(st[i].english) );
end;
end;
单击按钮“计算总成绩”实现对每个同学总成绩的计算,添加
Button1的 Button1Click事件,代码如下:
procedure TForm1.Button1Click(Sender,TObject);
begin
listbox6.Items.Clear ;
for i:=1 to 5 do
begin
listbox6.Items.Add(inttostr(st[i].philology+st[i].math
+st[i].english) );
end;
end;
单击按钮时运行结果如图 6-5所示。
图 6-5 对成绩的求和运行结果
6.4.3 记录的变体部分 (1)
一般的记录都有确定的字段和数据类型,但在现实生活中还有另外一种情况 。 如在学生登记表中有一项,入团时间,,如果该同学是共青团员,则在该字段中填上入团时间,如果该同学不是共青团员,那么这一部分就是空白 。 为了描述这一类记录,就要用到记录的变体部分,带有变体部分的记录类型的声明格式为:
Type
<记录类型名 >=Record
<字段名 1>:<类型 1>;
<字段名 2>:<类型 2>;
...
<字段名 n>:<类型 n>;
Case <识别字段名 >,<识别字段类型 > Of
<常量表 1>:<字段列表 1>;
<常量表 2>:<字段列表 2>;
...
<常量表 n>:<字段列表 n>;
end;
6.4.3 记录的变体部分 (2)
在保留字 case之前的声明部分与标准记录类型中的声明相同。从 case到
end之前最后一个分号( ;)之间叫做变体部分。
对于声明带有变体部分的记录类型应注意以下几点。
( 1)如记录类型中含有变体部分,则变体部分的声明应位于记录类型声明的最后部分,Case之前的声明与平常记录声明相同。
( 2) <识别字段名 >可以省略,如果省略 <识别字段名 >,那么也要同时忽略紧随其后的冒号(,)
( 3) <识别字段类型 >必须是顺序类型,不可以是实型、字符串等类型。如果是枚举类型或子界类型则必须事先声明。
( 4)每个 <常量表 n>都是一个表示 <识别字段类型 >类型的常量,或者逗号隔开的此类常量列表。在当前变体部分声明中,对于所有的 <常量表 n>,同一个值最多只能出现一次。其功能类似于 case语句中 <情况常量表 >与 <选择器表达式 >的关系。
( 5) <字段列表 n>的声明方法与普通记录各字段的声明方法相同,一般格式为:
(<字段名 1>:<类型 1>;<字段名 2>:<类型 2>;...<字段名 n>:<类型 n>)
该记录中用 ifmember判断是否团员,如果是团员则用 year字段来描述入团年份,
用 month来描述入团月份,如果不是团员则没有相关字段。
( 6)可变体部分的字段的类型不能是长字符串类型 (string)和可变体类型
(variant),同样也不能是包含这两数据类型的构造类型。
6.5 面向对象程序设计在第 1章简单介绍了关于面向对象程序设计的基本知识,提到了对象及类的概念,但在 Delphi 7.0 编程中具体是如何实现类和对象定义及使用呢? 本节就主要介绍在 Object Pascal中有关面向对象程序设计的内容 。
6.5.1 类和对象的定义 (1)
类是一种抽象的数据类型,而对象则是某一类的实体对象。一个对象与它所属类的关系就好比一个具体的整数与整数类型的关系,没有离开类的对象,
类与对象是密切相关的。
1,类是一种比较特殊的数据类型,它有以下几个主要特点
( 1)封装性
( 2)继承性
( 3)多态性
6.5.1 类和对象的定义 (1)
2,定义一个类定义一个类的格式是:
Type
<类名 >=Class (<父类名 >)
<类成员 >
end;
注意,Object Pascal类的声明只能出现在 Program单元或
Unit单元最外层作用域的类型定义部分。
类名可以是任何合法的标识符,在 Object Pascal中类名一般用 T打头,以区别于其他数据类型。 Class是保留字,是用于声明类的。 Class 后面的父类名表示当前声明的类是从父类名制定的类中继承而来的,声明的类称为父类的子类,该子类将继承父类的所有成员。“父类名”可以省略,此时表示类是继承缺省的类 TObject。类声明中可以没有成员列表,如果需要,类主要有两种类成员,分别是 Field(字段)和 Method(方法)。 Field对类的对象所需要用到的各种变量进行说明,Method对类的对象包含的各种过程与函数进行说明。类的声明中如果含有字段成员,那么字段成员的声明必须先于方法成员的声明。
跟其他数据类型不同
6.5.1 类和对象的定义 (2)
3,定义一个对象类是一种数据类型,声明了一个类之后就可以定义一个对象,对象是类的一个实例。对象与类的关系如同一个整数变量与整型的关系。定义对象的格式是:
var <对象名 >:<类名 >
(具体例子见本教程 P96页 )
的是类的声明只能出现在 Program单元或 Unit单元最外层作用域的类型定义部分,而不能定义在变量说明部分或一个过程或函数内。因此,类的作用总是全局的。
6.5.2 类和对象的使用 (1)
访问一个对象的属性和方法的格式如下:
<对象名 >.<属性或方法 >;
使用对象的方法时,应包括对应的参数。
要改变一个对象的某个属性或是调用它的一个方法,必须在这个属性名称或调用方法之前加上这个对象的名称。例如,窗体上有一个编辑框组件,需要 在运行中改变它的 Text属性,则编写下列的代码:
Edit1.Text,= 'Welcome to Delphi';
同样,清除编辑框组件中选中的文本,可以调用 TEdit组件的相应方法:
Edit1.ClearSelection;
如果想改变一个窗体对象中一个对象域的多个属性或调用多个方法时,使用 With语句可以简化程序。 With语句在对象中可以和在记录中一样方便地使用。
使用 With语句不必在每一个属性或方法前加上 ListBox1标识符,在 With语句之内,所有的属性或调用方法对于 ListBox这个对象而言都是在它的范围内。
6.5.2 类和对象的使用 (2)
如果两个变量类型相同或兼容,可以把其中一个对象变量赋给另一个对象变量。例如,对象 TForm1和 TForm2都是从 TForm继承下来的类型,而且 Form1和 Form2已被说明过,那么就可以把 Form1赋给 Form2:
Form2,=Form1;
只要赋值的对象变量是被赋值的对象变量的祖先类型,就可以将一个对象变量赋给另一个对象变量。例如,下面是一个 TestForm的类型说明,在变量说明部分一共说明了两个变量,AForm和 BForm。
type
TestForm = class(TForm)
Button1:TButton;
Edit1:TEdit;
procedure Button1Click(Sender,TObject);
private
{私有域说明 }
public
{公有域说明 }
end;
var
AForm:TForm;
BForm:TestForm;
因为 TestForm是 TForm类型的子类,因此下面的赋值语句是合法的:
BForm,= AForm;
6.5.3 类的方法( 1)
方法是一个类可以进行操作的过程与函数,方法是属于类的数据的一部分,类的方法决定了由这个类所定义的对象所能执行的所有功能。
2,方法的类型对象的方法定义可以分以下几类:静态( Static)、虚拟( Virtual)
和动态( Dynamic)或消息处理( Message)。在方法声明后分别用保留字 Static,Virtual,Dynamic,Message进行说明,也可以不加保留字,
这种情况下声明的方法是静态的。 (例子见本教程 P99页
( 1)静态方法( 2)虚拟方法 ( 3)动态方法
1,方法的声明声明一个方法的格式同声明一个过程或函数的语法相似。
过程方法声明格式如下:
Procedure < 过程方法名 > [ ( < 形参表 > ) ];
函数方法声明格式如下:
Function <函数方法名 > [ ( < 形参表 > ) ],< 返回类型 >;
方法声明后必须在实现部分对方法进行代码定义。 (例子见本教程
P99页)
6.5.3 类的方法( 2)
( 2)析构函数析构函数的声明格式为:
Destructor <析构名 > ( [ 参数表 ] );
其中析构名可以是任何合法的标识符,不过按照 Object Pascal的习惯,析构名常使用 Destroy。析构的作用刚好与构造的作用相反,它用于删除对象并指定删除对象时的动作,通常是释放对象所占用的堆和先前占用的其他资源。
3,构造和析构构造( Constructors)、析构( Destructors)是类中两种特殊的方法,用于控制类对象创建及初始化、删除时的行为。一个类可以没有也可以多个构造函数和析构函数,构造函数和析构函数可以被继承。
( 1)构造函数构造函数的声明格式为:
Constructor <构造名 > ( [ 参数表 ] );
其中构造名可以是任何合法的标识符,不过按照 Object
Pascal的习 惯,构造名常使用 Create。