资源描述
第三章 程序设计语言
返回
所谓程序设计语言就是计算机所能识别的代码,计算机代码通常要能够向计算机描述清楚做什么,用什么做这两个问题,因此计算机代码的一般形式是:
操作码 目的操作数 源操作数
操作码向计算机描述做什么,操作数向计算机描述用什么做的问题。所谓计算机的程序就是用计算机语言书写的、能完成一定功能代码序列。随着计算机技术的发展,用于程序设计的计算机语言也不断的向语言更加丰富、语句更容易理解的方向发展,以扩大计算机的应用范围。
§3.1 程序设计语言的分类
§3.1.1低级程序设计语言
低级程序设计语言提供的语句是计算机所能进行的基本操作,如:数据传送指令;算术运算指令;逻辑运算指令;串操作指令;控制转移指令;条件转移指令;控制指令;位操作指令等,这些操作和我们日常用语差别很大。理解它们需要对计算机结构有一定的了解。
1、 机器语言
计算机所能直接接受的只能是‘0’、‘1’这样的二进制信息,因此最初的计算机代码的操作码、操作数都是用二进制形式表示的,利用机器语言编写程序,要求程序设计人员熟记计算机的全部指令,工作量大、容易出错又不容易修改。同时各种计算机系统的机器指令也不一定相同,所编制的程序只适用于特定的计算机系统。因此,利用机器语言编写程序对非专职程序设计人员几乎是不可能的。
2、 汇编语言
由于机器语言编写程序困难很大,出现了用符号来表示二进制指令代码的符号语言,称为汇编语言。汇编语言用容易记忆的英文单词缩写代替约定的指令例如用MOV表示数据的传送指令、IN表示从给定的端口输入数据到目的操作数中,OUT表示将源操作数的内容通过目的操作数指明的地址输出;用ADD表示加法指令,SUB表示减法指令等等。汇编语言的出现使得程序的编写方便了许多,并且编写的程序便于检查和修改。
汇编语言仍然是面向机器的程序设计语言,与具体的计算机硬件有着密切的关系,汇编语言指令与机器语言指令基本上是一一对应的,利用汇编语言编写程序必须了解机器的某些细节,如累加器的个数、每条指令的执行速度、内存容量等等,因此汇编程序的编写、阅读对非计算机专业的技术人员来说,依然存在着很大的障碍,下面是一个利用80386/80286汇编语言编写的程序。
例1 求分段函数
-1 x﹤0
y= 0 x=0
1 x﹥0
的函数值。
DATA SEGMENT ;数据段开始
XX DB X
YY DB ?
DATA ENDS ;数据段结束
CODE SEGMENT ;代码开始
ASSUMS CS:CODE,DS:DATA ;规定CS段装代码,DS段装数据
START:MOV AX,DATA ;程序开始,将数据传送到累加器
MOV DS,AX ;将累加器的数据装DS段
MOV AL,XX ;将x数据传送到累加器
CMP AL,0 ;将AL数据与0比较
JGE BIGR ;如果大于等于0转到BIGR
MOV AL 0FFH
MOV YY AL ; x﹤0,将-1传送到YY
HLT
BIGR:JE EQUT
MOV AL,01H
MOV YY,AL ; x﹥0,将1传送到YY
HLT
EQUT:MOV YY,AL ; x=0,将AL的数据0传送到YY
HLT
CODS ENDS ; 代码结束
END START ; 程序结束
从上面的程序可以看到,利用汇编语言编写程序,编程人员必须了解计算机系统的累加器、各种寄存器、存储单元,对计算机的硬件资源有一定的了解。
计算机所能直接接受的是二进制信息,因此利用汇编语言编写的程序,必须经过翻译,转化为机器语言代码才能在计算机上运行,这个过程是通过一个翻译程序自动完成的,将汇编程序翻译成机器代码语言程序的翻译程序通常称为汇编程序,其过程可以用图2.1描述
汇编语言源文件
目标文件
可执行文件
汇编软件 连接软件
图2.1 汇编语言程序的运行过程
§3.1.2高级程序设计语言
所谓高级程序设计语言是接近于自然语言或数学语言的计算机语言。利用高级语言编写程序,编程者不需要掌握过多的计算机专业知识,特别适合于非计算机专业的专业技术人员利用计算机技术解决本专业的问题,高级语言的产生,大大扩展了计算机的应用范围,推动了各行各业的发展。高级语言分为过程化语言和非过程化语言。
§3.2 面向过程的程序的程序设计基本特征
所谓计算机程序,就是把完成某项任务的具体步骤,利用计算机语言提供的语句(指令)描述出来,形成的语句序列。过程化的程序设计语言是接近于数学语言的计算机语言。利用过程化程序设计语言设计程序,完成一定的任务,无论所完成的任务简单或者复杂,都必须将具体的步骤描述清楚。例如,利用高级语言编写程序完成两个整数相加的程序,必须描述以下步骤
定义三个变量x,y,z分别用来存放被加数、加数与和
将加数、被加数分别输入到变量x,y中
计算x+y的值,并将结果存入变量z中
把变数z的值输出
程序结束
完成某项任务的具体步骤通常称为算法,所以过程化的程序设计语言也称算法语言。
§3.2.1 过程化语言的种类
过程化程序设计语言有很多种,每一种语言都有各自的特点,较为常用的有以下几种:
FORTRAN语言:FORTRAN语言是最早、最常用的科学和工程计算语言,采用了结构化的程序设计思想,其程序结构是分块结构。一个FORTRAN程序由一个主程序块和若干个子程序块组成,程序的执行从主程序开始,主程序可以调用子程序,子程序也可以调用子程序。FORTRAN语言提供高精度的数据类型,特别适用于工程计算;并且FORTRAN程序的结构比较简单,可以分块书写,分块编译,使用起来灵活、方便。
BASIC语言:BASIC语言是适合于广大初学者的一种计算机语言,其语句结构简单。BASIC语言采用了结构化的程序设计思想,一个BASIC程序由一个主程序块和若干个子程序块组成。程序的执行从主程序开始,主程序可以调用子程序,子程序也可以调用子程序。BASIC语言可以实现递归调用,有较强的作图功能,具有良好的编辑环境,友好的用户接口,可以使用键盘和鼠标,有功能丰富的联机‘帮助’系统,提供‘分步’和‘跟踪’等调试工具,可以说BASIC语言功能全、编程简单,程序容易理解,特别适用于帮助初学者进入计算机应用大门。
PASCAL语言:PASCAL语言是一种典型的系统结构化语言,PASCAL语言的出现和结构化程序设计技术的发展,推动了编译程序工程技术的发展。PASCAL语言强调概念清晰,实现简化,方便用户;具有丰富的数据类型,便于用户组织和处理各种形式的数据。
C语言:C语言是一种短小精悍的计算机程序设计语言,它根据结构化程序设计原则设计并实现。C语言具有丰富的数据类型;为结构化程序设计提供了各种控制结构和数据结构;具有丰富的运算符和表达式,能实现汇编语言中的大部分功能;C语言还有丰富的标准函数库,调用这些标准函数可以操作计算机的硬件、进行动态地址的分配、绘图等功能,因此C语言具有表达力强、编译出的目标程序质量高、语言简单灵活、易于实现等特点,有时C语言被称为是介于高级语言与低级语言之间的中级语言。C语言不仅可以用来写操作系统、编译程序,也可以用来编写写各种应用软件,C语言已成为当今最流行的程序设计语言。
§3.2.2过程化语言的编程特点
各种高级的过程化语言各有自己的特点,但它们的语句基本上是相同的;在使用这些编程语言进行编程时,编程的方法也基本相同;结构化程序设计语言每个程序模块的格式基本是相同的。下面是各个模块的基本模式
程序模块的开始
程序模块的必要说明(如函数调用的说明等)
程序模块中使用的常量、变量的定义
数据的输入
数据的处理
数据处理结果的输出
程序模块的结束
下面是用不同的程序设计语言编写的解决同一个问题的程序,可以使读者从中体会,用不同语言编写程序的相同点和不同点。
例2 编写程序计算 ∑(2i+1)!
① FORTRAN语言程序
INTEGER I,J,FUN,SUM 变量的定义
SUM=0 给变量赋初值
DO 10 I=0,10
FUN=1
DO 20 J=1,2*I+1
FUN=FUN*J 数据的处理
20 CONTINUE
SUM=SUM+FUN
10 CONTINUE
WRITE(*,100)SUM 数据的输出
100 FORMAT(1X,I10)
101 END 程序结束
② BASIC语言程序
DIM I AS INTEGER
DIM J AS INTEGER 变量的定义
DIM FUN AS INTEGER
DIM SUM AS INTEGER
SUM=0 给变量赋初值
FOR I=0 TO 10
FUN=1
FOR J=1 TO 2*I+1
FUN=FUN*J 数据的处理
NEXT
SUM=SUM+FUN
NEXT
PRINT SUM 数据的输出
END 程序结束
③ PASCAL语言程序
PROGRAM mysum(input,output)
VAR
I,J,FUN,SUM:INTEGER; 变量的定义
BEGIN 程序开始
SUM:=0; 给变量赋初值
FOR I:=0 TO 10 DO
BEGIN
FUN=1;
FOR J:=1 TO 2*I+1 DO 数据的处理
FUN=FUN*J;
SUM=SUM+FUN;
END
WRITELN(SUM); 数据的输出
END 程序结束
④ C语言程序
main() 程序开始
{
int i,j,fun,sum; 变量的定义
sum=0; 给变量赋初值
for (i=0;i﹤=10;i++)
{
fun=1;
for(j=1;j﹤=2*i+1;j++) 数据的处理
fun=fun*j;
sum=sum+fun;
}
printf(“sum=,%d”,sum); 数据的输出
} 程序结束
从这个例子我们可以清楚的看到不同的高级语言编写程序的基本格式是相同,提供的相同功能的语句,其形式也大同小异,只是在一些语法点上有些差异,如果熟练掌握其中的一种语言,就不难读懂用其它语言编写的程序。
§3.2.3过程化语言程序的执行过程
前面我们提到,计算机所能直接接受的是二进制信息,利用高级语言编写的程序,应转变为机器代码,才能在计算机上运行。利用高级语言编写程序的过程是:借助每种语言提供的各自的编辑软件生成各自的高级语言源程序;利用各自的翻译程序(编译或解释程序)将高级语言源程序自动翻译成目标程序(.obj文件);再将目标程序通过连接程序自动生成可执行文件。整个过程可以用图2.2表示。
高级语言
源程序文件
目标文件
可执行文件
高级语言
源程序清单
编辑软件 翻译软件 连接软件
图2.2 高级语言程序的执行过程
随着计算机的发展出现了高级语言各自的集成化的环境,所谓集成化环境就是将程序的编辑、编译或解释、连接、运行的操作集成在一个环境中,各种命令设计成菜单命令,这样,更加方便了非计算机专业人员掌握利用高级语言设计程序的过程。在集成环境中除了关于程序的主要操作命令外,还设计了关于文件操作的命令(打开、存盘、关闭等)、程序调试命令(分步操作、跟踪、环境设置等)等等,方便了编程者在集成环境下进行程序的编写、调试、运行。
§3.2.4非过程化程序设计语言
非过程化的程序设计语言是接近于自然语言的计算机语言。利用非过程化语言编写程序往往只需要通知系统做什么,而不需要说明怎么做。典型的非过程化程序设计语言是各种类型的数据库语言,例如利用FOX系列的数据库管理系统提供的数据库语言,编写将数据库中的数据记录按某个字段进行排序的程序如下:
select 1 选择工作区
use student 打开数据库
sort to st1 on grade / d for 性别=‘女’ 对女同学按成绩降序排序
use 关闭数据库
通过执行上面的程序,就可将数据库student全体女同学的数据记录进行排序,生成一个新的数据库st1,其记录是按照女同学的成绩从高分到低分排序。
非过程化程序设计语言也有很多种类,其中数据库语言是典型的非过程化语言,最流行的数据库语言是关系型的数据库语言:FOX系列,如从最早的DOS环境的Dbase、Foxbase,到Windows环境下的Foxpro,可视化的Visual Foxpro,各种数据库语言编写的程序虽然有一定的差别,但总的程序结构是相同的,与过程化语言一样,只要掌握了其中的一种,就能读懂用其它数据库语言编写的程序。
§3.3.5 过程化程序设计语言的特点
过程化程序设计语言自20世纪50年代问世以来已有一千多种,虽然每种语言都有自己的特点,都是针对不同的使用者设计的,但是过程化程序设计语言都有共同的特点。
§3.3.5 .1常量、变量、表达式
1、常量:计算机语言中提到的常量指的是常数,从这一点上说计算机语言中常量的概念和数学上常量的概念相同,但与数学上常量的概念也有不同,在计算机语言中常量有一定的类型、有严格的表示方式。不同的计算机语言提供的数据类型不同,常用的数据类型有整型、浮点型、字符型,有的计算机语言也提供逻辑型的数据类型,由于数据的类型不同,计算机系统提供的存放数据的存储单元(字节数)不同,因此在计算机程序中使用数据时,一定要明确指出数据的类型,这一点与我们在日常中使用常量的概念是有差异的。另外在计算机语言中,对常量的表示,不同的计算机语言都有自己的语法规定,程序设计者在编写程序时应按照相应语言的语法规定严格书写,以免编译错误。
2、变量:计算机语言中提到的变量的概念,可以这样理解:变量是用来存放常量的,因为常量是有类型的,存放常量的变量也应该是有类型的,在计算机语言中规定程序中使用的变量必须先定义,后使用。程序中定义一个变量,在编译该程序时编译系统为该变量分配相应的存储单元,变量和存储单元之间的关系可以用图2.3表示。
变量名
相应的存储单元
图2.3 高级语言中变量与存储单元的对应关系
即一个变量名对应一个存储单元(整型变量对应整型的存储单元、浮点型变量对应浮点型的存储单元),在高级语言中用变量名的方式对存储单元进行访问,这些访问包括从存储单元中读数、向存储单元中存数,把存储单元的数据输出等等。不同的高级语言,对变量名的规定、对变量的定义方式都有各自的语法规定,程序设计者在使用某种高级语言编写程序时,要严格按照使用的高级语言的语法规定定义变量。
3、表达式:高级程序设计语言中用表达式进行运算,所谓表达式就是把常量、变量和其它形式的数据用运算符连接起来的式子。高级语言中的运算符分为:
算术运算符:加、减、乘、除、乘方
关系运算符:大于、小于、等于、大于等于、小于等于、不等于
逻辑运算符:与、或、非
字符运算符:字符连接
高级语言中,根据表达式结果类型不同,表达式分可为:算术表达式;逻辑表达式、字符表达式,其中算术运算的结果是算术量,关系运算、逻辑运算的结果是逻辑量,字符运算的结果是字符量,各种运算符有不同的优先级别。在程序设计中,表达式的使用最为频繁,因此程序设计者在设计程序时,必须严格按照所使用的编程语言的语法规定书写表达式(包括算运符、格式、是否添加括号、运算优先级别等)确保编译系统所识别的表达式与实际表达式一致。
§3.3.5.2赋值语句,输入、输出语句
1、赋值语句:赋值语句是高级程序设计语言中使用最频繁的数据处理语句,其功能是完成数据的运算和存储。程序设计需要进行某种运算时,通常是将该运算通过一个表达式表示出来,交给计算机来完成,运算的结果存储到计算机的存储单元中,以备后面的数据处理(读取、输出等)使用,在高级语言中使用赋值语句实现上述过程。赋值语句的一般格式为:
变量名 赋值号 表达式
在上式中,变量名代表计算机的存储单元,表达式表示所进行的运算,不同的高级语言,赋值号的形式不同,通常使用数学中的“=”作为赋值号,读者切勿将赋值号理解为等号。如:C语言中的语句 x=x+1; 表示的意义是将变量x存储单元中的数据读出,完成加1运算后,再将运算的结果存入变量x存储单元中,切勿将上式理解为x等于x+1。
2、输入语句:输入语句也是程序设计中经常使用的语句,用来从外部设备获得数据处理中所需要的数据。通过设置输入语句,程序在的运行过程中需要数据时,系统从指定的外设中读取数据,因此在输入语句中要描述:
①输入什么数据;
②用什么格式输入;
③使用什么设备输入;
我们来看C语言中的两个典型的输入语句:
scanf(“x=%d,y=%f① 按什么格式输入
”,x,y② 输入什么数据
);
fscanf ( fp③ 从什么设备输入数据
, “%s%c”, str , x);
在上面的两个输入语句中分别指出了输入什么数据、用什么格式输入、从什么设备输入这几个问题,虽然在scanf函数中没有指出输入数据的设备,但是该语句隐含着使用系统默认的输入设备(键盘)进行输入。各种不同的高级语言使用不同的语句、格式描述着相同的意思。
3、输出语句:输出语句是程序设计中不可缺少的语句,只有通过输出语句,程序员才可看到程序进行数据处理的结果。通过设置输出语句,在程序运行过程中有数据需要输出时,系统将会把计算机存储单元中的数据按照指定的格式输出到指定的输出设备上,因此在输出语句中同样要描述:
①输出什么数据;
②用什么格式输出;
③使用什么设备输出;
我们同样来看C语言中的两个典型的输出语句,在这两条语句中指出了输出什么数据、用什么格式输出、从什么设备输出这几个问题,虽然在printf函数中没有指出输出数据的设备,但是该语句隐含着使用系统默认的输出设备(显示器)进行输出。
printf(“x=%d,y=%f”,a,b);
fprintf(fp,”x=%d,y=%f”,a,b);
§3.3.5.3数组、链接表
数组和链接表是高级语言在程序设计中使用的组织数据和存储数据的方式。
1、数组:在程序设计中经常使用数组来存放一组同类型的数据,在程序中定义一个数组,系统将为这个数组开辟一组同类型的存储单元来存放数据,例如在C语言中的数组说明形式为:
float a[10];
则程序在运行时将为数组a开辟10个连续的浮点型的存储单元,可以用来存放10个浮点型的数据,对这十个浮点型的数据可以通过数组元素a[0]、a[1]、a[2]、a[3]、a[4]、a[5]、a[6]、a[7]、a[8]、a[9]方便的进行操作,这种通过数组元素下标的改变就可以方便的访问到各个数据的方式,可以使我们编写程序变得非常简洁,例如可以使用循环结构方便的访问数组中的每个数据:
for(i=0;i<n;i++)
sum=sum+a[i];
上述语句结构可以实现若干个同类型数据的相加运算。当然若干个数据相加的运算也可以通过下面的赋值语句实现:
sum=a0+a2+a3+a4+a5+a6+a7+a8+a9;
其中,进行相加的数据存放在变量a0、a1、…、a9中,读者可以从中体会使用数组和不使用数组在编写程序时算法上的差异。
2、链接表:链接表是一组数据的存储方式。把一组数据存储到一组具有链接关系的存储单元中,可以节省计算机的存储单元,优化存储结构,链接表是通过编写程序来建立的,在进行数据的访问时,应本着怎么建立怎么访问的原则。下面是一个单链表的建立和单链表访问的程序段:
struct node
{int data;
struct node *next;
}
void creat-read ( )
{ int num,n
struct node *head,*s,*p;
printf(“请输入链表中存入数据的个数:”);
scanf(“%d”,&n);
head=(struct node *)malloc(sizeof(struct node));
p=head;
while(n>0)
{ printf(“请输入结点的数据\n”)
scanf(“%d”,&num); 建立单链表
s=(struct node *)malloc(sizeof(struct node));
s->data=num;
p-next=s;
p=s;
n=n-1;
}
p->next=null;
p=head->next;
while(p!=null)
{printf(“%d”,p->data); 访问单链表中的数据
p=p->next;
}
}
从上面的例子中,我们可以看到链表是一种存储方式,这种存储方式的使用,优化了对计算机资源的运用,提高了存储的效率,程序的编写也将采用与存储相关的算法,即本着怎么存储,怎么访问的原则。
§3.3.5.4程序的控制结构
高级语言中,使用三种结构化的控制结构,实现模块化的程序设计,这三种控制结构分别是顺序结构、选择结构和循环结构。不同的高级语言中使用不同形式的语句结构来实现这三种控制结构,下面是C语言中实现这三种控制结构的语句结构。
1、 顺序结构:顺序结构是按照一定的运算顺序,依次执行完成指定的运算功能。高级语言程序执行的过程,就是按照语句的顺序依次执行的,因此实现顺序控制结构的语句结构不需要特殊的控制语句,只需按照算法的顺序依次以高级语言语句的形式描述为程序即可。例如:
main()
{int x,y,z;
scanf(“%d%d”,&x,&y);
z=x+y;
printf(“输入的两个数相加的结果是:%d”,z);
}
上述程序完成的功能是从键盘输入两个数,存入变量X,Y中;将输入的两个数相加,结果存入变量Z;将变量Z的值输出到显示器上。
2、选择结构:选择结构是根据给定的逻辑表达式,计算逻辑表达式的值,当其值为真时,控制流程去执行一种操作;当其值为假时,控制流程去执行另一种操作的语句结构,例如:
main()
{float x,y;
scanf(“%f”,&x);
if(x<0)
y=-x*x;
else
y=x*x;
printf(“函数的值为:%f\n”,y);
}
上述程序的功能是计算分段函数
-x2 x<0
y=
x2 x≥0
的函数值,从键盘输入一个自变量X的值,判断其是否小于零,若小于零就执行赋值语句:y=-x*x; 若不小于零就执行赋值语句:y=x*x; 选择结构控制流程无论执行了那一条赋值语句后,都转到printf语句去执行。
各种高级语言中都提供了多种完成这种程序结构的语句结构,上面的if…else…结构只是这多种语句结构中的一种。
3、循环结构:顺序结构、选择结构的算法与我们日常处理问题的思路基本相同,而循环结构是计算机语言所具有的特殊的算法,它利用计算机语言中变量的特点
变量 存储单元
将一些有规律的运算通过循环执行一条或多条语句来实现,循环语句控制流程,反复执行一条或多条语句(循环体),例
main()
{int i=1 ,sum=0;
while (i<100)
{sum=sum+i;
i=i+1;
}
printf(“1+2+…+99=%d”,sum);
}
上面的while语句具有控制流程的功能。当条件表达式:i<100的值为真时反复执行赋值语句sum=sum+i;和i=i+1;直到条件表达式:i<100的值为假时,流程才会转到printf语句去执行。
与选择结构相同,各种高级语言中都提供了多种完成这种程序结构的语句结构,上面的while结构只是这多种语句结构中的一种。
通常一个高级语言的程序可能只包含这三种语句结构中的一种,而更多的情况是既包含顺序结构也包含选择结构,同时也有循环结构,一个程序的具体结构应视我们所解决的问题而定。
§3.3.5.5 子程序、函数、过程
子程序、函数和过程从某种程度上说,应该是同一概念,只是在不同的高级语言中提法不同,它们都是高级语言中提供的实现模块化程序设计和简化程序代码的途径,通常一个子程序、一个函数或一个过程用来完成一个特定的功能,它们可以被主程序模块或其它程序模块调用,有些高级语言中还允许它们自己调用自己(递归调用)。如在pascal语言中用过程、函数来实现模块化设计;在C语言中用函数实现模块化设计;在basic、fortran语言中用子程序、函数来实现模块化设计。不同的高级语言中子程序、函数和过程的语句形式有一定的差异,但它们基本思想是相同的,编写的方法也基本相同。子程序、函数或过程编程方法是:
1、 定义子程序、函数或过程;
2、 定义主调模块和被调模块之间的参数及参数传递方式;
3、 在主调模块中正确的调用被调用模块。
§3.3 面向对象程序设计语言的基本特征
面向对象是一种新的程序设计方法。面向对象程序设计方法的基本思想是:从客观存在的事物(对象)出发,以尽可能接近人类思维的方式建立模型,对客观事物进行结构模拟和行为模拟。
§3.3.1面向对象的基本概念
面向对象的基本概念包括对象、属性、方法、消息、封装、类、继承、多继承等。下面对这几个概念分别进行介绍。
对象:由一组属性和对这组属性进行操作的一组方法构成。
属性:是用来描述对象静态特征的一个数据项。如一个学生的姓名、学号、性别、出生日期等
方法:是用来描述对象动态特征的一个操作序列。如对学生数据的输入、输出、按出生日期排序、查找某个学生的信息等。
消息:是用来请求对象执行某一操作或回答某些信息的要求。实际上是一个对象对另一个对象的调用,如一个对象调用学生对象,申请学生信息的查询。
封装:是一种信息隐蔽技术。对象本身就是一种封装,把一组属性和对这组属性进行的操作结合成一个独立的系统单位,并尽可能隐蔽对象的内部细节。
对象类:类是具有相同属性和方法的一组对象的集合,它为属于该类的全部对象提供了统一的抽象描述。在系统中通常有很多相似的对象,它们具有相同名称和类型的属性、响应相同的消息、使用相同的方法。对每个这样的对象单独进行定义是很浪费的,因此,我们将相似的对象分组形成一个类,每个这样的对象被称为类的一个实例,一个类中的所有对象共享一个公共的定义,尽管它们对属性所赋予的值不同。例如,所有的雇员构成雇员类,所有的客户构成客户类等。
继承:一个系统中通常包含很多的类,然而通常有些类是相似的。例如,银行系统中的客户类与雇员类相似,它们都定义了姓名、性别、出生年月等属性。不过,也有些属性是雇员类所特有的(如工资)或客户类所特有的(如资信状况)。我们希望将那些共同的变量定义在同一个地方,只有将雇员和客户合并到一个类中我们才能做到这一点。为了允许直接表示类之间的相似性,需要将类放入一个特殊化层次中。例如,学校领导是职工的一个特殊化,因为所有领导的集合是所有职工的集合的子集,换句话说,每一个领导都是单位的一个职工。类似地,群众也是职工的一个特殊化。类构成特殊化层次(1SA联系)。ISA联系中子类的对象拥有其超类对象全部的属性和方法,称为子类对超类的继承。图3.4是组织部门的类层次结构。
职工
领导 群众
校长 处长 科长 教师 科员
图3.4 学校应用的类层次结构图
一个类可以从多个超类中继承属性和方法,称作多继承。在多继承的情况下,类和子类的关系可以用一个有向无环图来表示,其中一个类可以有多于一个的超类。图3.5中的教师领导就有两个超类:领导和教师,即教师领导既继承了领导的属性也继承了教师的属性。
职工
领导 群众
校长 处长 科长 教师 科员
教师领导
图3.5 多继承示例
对象的标识:在面向对象系统中一个对象通常对应着现实世界中的一个实体。一个实体保持自身的标识不变。类似地,一个对象也保持自己的标识不变,即使它的一些或者全部属性的值或方法的定义多次改变。
对象的标识是一种概念上的东西,实际的系统需要一种物理机制来唯一标识对象。面向对象系统提供了一种对象标识符的概念来标识对象。对象标识符是唯一的,也就是说每个对象具有单一的标识符,并且没有两个对象具有相同的标识符。
对象包含:一个(或一些)对象是另一个对象的组成部分称做对象包含,包含其它对象的对象称为复杂对象或复合对象。图3.6是自行车结构系统的对象包含层次。
自行车
车轮 车闸 车架
轮框 辐条 轮胎 传杆 闸盒 闸线
图3.6 自行车结构系统的对象包含层次
§3.3.2面向对象程序设计的特征
面向对象语言也是高级程序设计语言,它是过程化程序设计语言的进一步发展。编写过程化程序的方法是:按照解题模型精心设计数据结构和算法,用过程化程序设计语言描述算法,即可写出程序。过程化程序的程序结构是层层调用,如同一棵树,下层程序除自己声明的数据外共享上层和上层程序声明的数据。图3.7中子程序SUB1、SUB2如果都用到主程序声明的数据,它们之间就有关系:一个子程序改动了共享数据则另一个必然受影响,我们称它为数据耦合。
Main() program
调用SUB1
调用SUB2
END
子程序SUB1
调用A1
调用A2
END
子程序A1
END
子程序A2
END
子程序B1
END
子程序B2
END
子程序SUB2
调用B1
调用B2
END
图3.7 过程式程序的结构
模块化程序设计的原则虽然将大程序划分成若干个小程序模块,但每个程序模块独立性并不强。所谓独立性是指修改 (甚至删除) 了一个模块对其他程序块没有影响。如果子程序分得更小,一个模块只实现一种功能,子模块数量上去了,独立性就相对增强一些(有更多模块不共享数据),近代软件,过程小而多是其特色。尽管如此,有了共享数据,当程序规模进一步增大时查错、调试仍然极其困难。试设想有100个子程序模块,每个模块都单独测试过,合在—起调试时总出错。我们只好沿其执行流程去找,如图3.7箭头所示。但是由于程序中有条件判断,可能跳过某些模块,执行流程因输入值不同而不同,模块越多可能的流程就越多,测试的困难就越大。“分而治之”的思想使我们想到进—步封装。
即把相关的数据与过程封装在一起,尽可能让它们独立。其示意图如图3.8所示。计算机软件技术基础设想有一程序有100个子程序,经过分析,这100个子程序并不是每个子程序都要用到所有的数据,把数据相关和程序相关(有嵌套调用)的模块分成组。
数据组0
主程序
数据组1
SUB1—SUB35
数据组2
SUB36—SUB76
数据组3
SUB77—SUB100
图3.8 程序模块被分成3组
例如,可以看到Sub1~Sub35加工第1组数据,S
展开阅读全文