201311程序员下午真题
第 1 题
阅读以下说明和流程图,填补流程空中的空缺(1)~(5)将解答填入答题纸的对应栏内。
【说明】
两个包含有限个元素的非空集合 A、B 的相似度定义为 |A∩B|/|A∪B|,即它们的交集大小(元素个数)与并集大小之比。
以下的流程图计算两个非空整数集合(以数组表示)的交集和井集,并计算其相似度。己知整数组 A[1:m]和 B[1:n]分别存储了集合 A 和 B 的元素(每个集合中包含的元素各不相同),其交集存放于数组C[1:s],并集存放于数组D[1:t] ,集合A 和 B 的相似度存放于 SIM。
例如,假设 A={ 1, 2 ,3,4} ,B={ 1, 4 ,5,6},则C={1, 4} ,D={1, 2 ,3 ,4 ,5, 6},A 与 B 的相似度 SIM=1/3。
【流程图】
答案与解析
- 试题难度:较难
- 知识点:流程图>流程图
- 试题答案:(1)s (2)t (3)c[s] (4)D[t] (5)s/t
- 试题解析:本题考查程序处理流程图的设计能力。
首先我们来理解两个有限集合的相似度自含义。两个包含有限个元素的非空集合 A、B 的相似度定义为它们的交集大小(元素个数)与并集大小之比。如果两集合完全相等,则相似度必然为 1 (100%); 如果两集合完全X同(没有公共元素),则相似度必然为0; 如果集合A 中有一半元素就是集合B 的全部元素,而另一半元素不属于集合 B,则这两 个集合的相似度为 0.5(50%)。因此,这个定义符合人们的常理性认识。
在大数据应用中,经常要将很多有限集边行分类。例如,每天都有大量的新闻稿。
为了方便用户检索,需要将新闻稿分类。用付么标准来分类呢?每一篇新闻稿可以用其 中所有的关键词来表征。这些关键词的集合勒为这篇新闻稿的特征向量。两篇新闻稿是 否属于同一类,依赖于它们的关键词集合是否具有较高的相似度(公共关键词个数除以 总关键词个数)。搜索引擎可以将相似度超过一定水平的新闻稿作为同一类。从而,可以 将每天的新闻稿进行分类,就可以按用户的需要将某些类的新闻稿推送给相关的用户。
本题中的集合用整数组表示,因此,需要规定同一数组中的元素各不相同(集合中的元素是各不相同的)。题中,整数组 A[1:m] 阳 B[l:n]分别存储了集合 A 和 B 的元素。流程图的目标是将 A 、B 中相同的元素存放入数组C[ 1:s] (共s 个元素),并将 A 、B 中 的所有元素(相同元素只取一次)存放入数组 D[1:t] (共t 个元素),最后再计算集合 A 和 B 相似度的。
流程图中的第一步显然是将数组 A 中的全部元素放入数组 D 中。随后,只需要对数 组 B 中的每个元素进行判断,凡与数组 A 中某个元素相同时,就将其存入数组 C; 否则就续存入数组 D (注意,数组 D 中已有 m 个元素)。这需要对 j (遍历数组 B) 与 i (遍历数组 A) 进行两重循环。判断框 B[j]=A[i]f lG立时, B[j]应存入数组 C; 否则应继续 i 循环,直到循环结束仍没有相等情况出现时, j 先应将 B[j]存入数组 D。存入数组 C 之前, 需要将其下标 s 增 1; 存入数组 D 之前,需要将其下标 t 增 1。因此,初始时,应当给j 赋 0,使数组C 的存数从C[1]开始。从而,()处应填 s,(3)处应填c[s]。而数组D 是在已有 m 个元素后续存,所以,初始时,数 fi D 的下标 t 应当是 m ,续存是从D[m+1] 开始的。因此, (2) 处应填 t ,(的处应填D[]。
两重循环结束后,就要计算相似度的,将其赋予 SIM,因此(5) 处应填的。
第 2 题
【说明】
下面的函数 sort(int n,int a[])对保存在数在a中的整数序列进行非递减排序。由于该序列中的元素在一定范围内重复取值,因此排序方法是先计算出每个元素出现的次数并记录在数组b中,再从小到大顺序地排列各元素即可得到一个非递减有序序列。例如, 对于序列 6,5,6,9,6,4,8,6,5. 其元素在整数区间 [4,9]内取值,因此使数组元素 b[0] ~b[5]的下标。0~5分别对应数值4~9. 顺序地扫描序列的每一个元素并累计其出现的次数,即将 4的个数记入b[0],5的个数记b[1],依此类推,9的个数记入b[5]最后依次判断数组b的每个元素值,并将相应个数的数值顺序地写入结果序列即可。
【C 函数】
void sort(int n ,int a[ ])
{ int b;
int i ,k ,number;
int minimum = a[0] , maximum = a[0];
/ minimum 和 maximum 分别表示数组a的最小、最大元素值/
for(i=1;i<n;i++){
if( (1) ) minimum=a[j];
else
if( (2) ) maximum=a[i];
}
number = maximum - minimum + 1;
if (number<=1) return;
b = (int )calloc (number ,sizeof(int)) ;
}
/*按次序在数组 a 中写入排好的序列*/
i=(3) ;
for( k=0; k<number; k++ )
for(; (4) ; --b[k] )
a [i++] = minimum +(5);
}
答案与解析
- 试题难度:较难
- 知识点:C程序设计>C程序设计
- 试题答案:(1) a[i]<minimum ,或a[i]<= minimum ,或其等价形式
(2) a[i]>maximum ,或a[i]>= maximum ,或其等价形式
(3) 0
(4)b[k] ,或b[k]>0 ,或b[k]!=0 ,或其等价形式
(5)k - 试题解析:本题考查 C 程序的基本语法和运算逻辑。 首先应认真分析题目中的说明,然后确定代码结构和各变量的作用。
空(1)和 (2)所在 for 语句的功能是求出数组 a 中的最小元素 minimum 和最大元素 maxlmum 。在设置了minimum 和 maximum的初始值后,空(1)处的判断条件是只要目前的元素 a[i]小于 minimum ,就需要更新minimum ,反之,空(2)处的判断条件是只要目前的元素 a[i]大于 maximum ,就需 更新maximum ,因此空(1)处应填入 a[i]<minimum 或其等价方式,空 (2)处应填入 a[i] >maximum 或其等价方式。 minimum 和 maximum 的作用是要确定计数数组 b 的大小。
根据题目中的描述,序列中的每个元素 a[i]都对应到计数数组 b[]的一个元素 b[k] 对应方式为: k = a[i] -minimum ,其中minimum 是数组 a 中的最小元素,显然在计数时, 一个数值出现一次,就在对应的 b[k] 中累加一次。
空(3)~(5)所在的语句组是产生排序后的序列,重新写入数组 a。首先需明确
变量 i和 k 的作用,根据它们在该语句组中的出现位置, i用于表示数组 a 的元素下标, k 用于表示数组 b 中元素的下标,因此,空(3)处应填入 0 ,使得从数组a 中下标为 0 的数组元素开始。通过循环控制 "for( k=0; k<number; k++)"己经明确数组 b 的下标变化方式,而需要写入数组 a 的元素个数表示在 b[k] 中,所以 “ for(;(4); --b[k])”中空(4)处应填入 "b[k]>0" 或其等价形式。 (由于 b[k] 中记录的是元素 k+ minimum 的出 现次数,所以空(5)处应填入 "k",从而将元素值恢复后再写回去。
第 3 题
阅读以下说明和 C 代码,填充代码中的空缺,将解答填入答题纸的对应栏内。
【说明 1】
下面的函数 countChar(char *text)统计字符串 text 中不同的英文字母数和每个英文字母出现的次数(英文字母不区分大小写)。
【c代码1】
int countChar( char *text )
{
int i,sum = 0; /* sum 保存不同的英文字母数*/
char *ptr;
int c[26] = {0}; /*数组c保存每个英文字母出现的次数*/
/*c[0]记录字母A或a的次数,c[1] 记录字母B或b的次数,依此类推*/
ptr = (1) ;/*ptr初始时指向字符串的首字符*/
while (*ptr) {
if ( isupper(*ptr) )
c[*ptr - 'A']++;
e1se
if ( islower(*ptr) )
c[*ptr - 'a'] ++;
(2) ; /*指向下一个字符*/
}
for(i=0;i<26;i++)
if (3) sum++;
return sum;
}
【说明2】
将下面C代码2中的空缺补全后运行,使其产生以下输出。
f2:f2:f2:2
f3:f3: 1
【C代码2】
*include <stdio.h>
int f1 (int (*f) (int)) ;
int f2 (int) ;
int f3 (int) ;
int main ()
{
printf("%d\n" ,f1( (4) ));
printf("%d\n" ,f1( (5) ));
return 0;
}
int f1 ( int (*f) (int) )
{
int n = 0;
/*通过函数指针实现函数调用,以返回值作为循环条件*/
while ( (6) ) n++;
return n;
}
int f2(int n)
{
printf("f2: ");
return n*n-4;
}
int f3 (int n)
{
printf("f3: ");
return n-1;
} **答案与解析** - 试题难度:较难 - 知识点:C程序设计>C程序设计 - 试题答案:(1)text ,或&text[0] ,或其等价形式
(2)Ptr++ 或 ++ptr,或ptr=ptr+1,或ptr+=1
(3)c [i] ,或(*c+i)
(4) f2
(5) f3
(6)f(n),或(*f)(n)
- 试题解析:
首先应认真分析题目中的说明,然后确立代码结构和各变量的作用。
在函数 countChar(char *text)中来统计字符串 text中不同的英文字母数和每个英文字母出现的次数。用来表示计数值的数组元素c[i]需要与英文字母对应起来,方式为 c[0] 记录字母 A 或 a 的次数,c[1]记录字母 B 或 b 的次数,依此类推,因此 i=英文字母-'A' (英文字母为大写)或 i=英文字母-'a' (英文字母为小写)。
数据指针是指向数据的指针变量。数据指针ptr用来表示 text 中的每一个字符,初始时 ptr 指向第一个字符,因此空(1)处应填入"text" 或其等价方式,(2)处的作用 是随循环控制逐个指出 text 中的后续字符,因此空(2)处应填入 "ptr ++"或其等价方式。
显然,若 c[i]的值不为 0则表示字符‘A'+i 或'a'+i 出现了,反之,则表示字符‘A'+i或'a'+i未出现,因此在计算字符种类时只要判断 c[i]是否为 0 即可,因此空(3)处应填入"c[i]"或其等价形式 。
函数指针是指向函数的指针变量。根据代码 2 的声明 "int f1(int (*f)(int)) ";可知调用函数f1时,实参应该是函数名或函数指针,且函数名或函数指针指向的函数应有一个整型参数,返回值为整型,而f2和f3都是符合这种定义类型的函数。
C 代码 2 中,在 main 函数中两次调用了函数f1,分析运行结果可知,是先以f2为实参调用f1,然后以f3为实参调用 f1 ,因此空(4)和(5)分别填入"f2"或"f3"或它们的等价形式,在空(6)处应填入"f(n) "或其等价形式来实现最后对f2和f3的调用。
### 第 4 题
阅读以下说明和C程序,填充程序中的空缺,将解答填入答题纸的对应栏内。
【说明】
正整数n若是其平方数的尾部,则称n为同构数。例如,6是其平方数36的尾部,76是其平方数5776的尾部,6与76都是同构数。下面的程序求解不超过10000的所有同构数。
己知一位的同构数有三个: 1,5,6,到此二位同构数的个位数字只可能是1,5,6这三个数字。依此类推,更高位数同构数的个位数字也只可能是1,5,6 这三个数字。
下面程序的处理思路是:对不超过10000的每一个整数a,判断其个位数字,若为1、5或6,则将a 转换为字符串as,然后对a进行平方运算,并截取其尾部与as长度相等的若干字符形成字符串后与as比较,根据它们相等与否来断定a是否为同构数。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int myitoa(int ,char *); /*将整数转换为字符串*/
/* right取得指定字符串尾部长度为length的子串,返回所得子串的首字符指针*/
char *right(char*, int length);
int main ()
{
int a ,t; int len;
char as[10] ,rs[20];
printf("[1 ,10000]内的同构数: \r");
for(a=1;a<=10000;a++) {
t = (1) ; /*取整数a的个位数字*/
if (t!=1&& t!=5 && t!=6) continue;
len = myitoa(a ,as); /*数a转换为字符串,存入as */
myitoa(a*a, rs); /*数a的平方转换为字符串,存入rs */
/*比较字符串as与rs末尾长度为len的子串是否相等*/
if ( strcmp (as , (2) )==0 ) /*若相同则是同构数并输出*/
printf("%s的平方为%s\n" ,as,rs);
}
return 0;
}
int myitoa(int num ,char *s) /*将整数num转换为字符串存入s */
{
int i ,n = 0;
char ch;
/*从个位数开始,取num的每一位数字转换成字符后放入s[] */
while (num) {
s[n++] = (3) + '0' ;
num = num/10;
}
s[n]='\0';
for(i=0; i<n/2; i++) { /*将s中的字符串逆置*/
(4) ; s[i] = s[n-i-1]; S [n-i-1] = ch;
}
return n; /*返回输入参数num的位数*/
}
char *right(char *ms ,int length)
/*取字符串ms尾部长度为length的子串,返回所得子串的首字符指针*/
{
int i;
for( ; *ms; ms++); /*使ms到达原字符串的尾部*/
for( i=0; i<length; (5) );/*使ms指向所得子串的首部字符*/
return ms;
} **答案与解析** - 试题难度:较难 - 知识点:C程序设计>C程序设计 - 试题答案:
(1)a%10,或其等价形式
(2)right(rs,len)
(3)num%10 ,或其等价形式
(4)ch = s[i],或ch = *(s+i)
(5) i++,ms--,或ms--,i++,或其等价形式 - 试题解析:本题考查C语言语法、数据指针和运算逻辑的应用。首先应认真分析题目中的说明,然后确是代码结构和各变量的作用。 根据题目中的叙述,同构数的个位数为1、5 或 6,因此,对于不超过10000的每个整数,应先获取其个位数字,因此空(1)处应填入"a %10"或其等价形式,从而可以先过滤掉不可能是同构数的数。根据代码中的注释,通过以下运算后,得到由a中数值转换所得的字符串as,以及a的平方所得数值转换得到的字符串rs,此后通过字符串比较运算来判断是否为同构数。
len = myitoa(a ,as); /*数a转换为字符串,存入as*/
myitoa(a*a ,rs); /*数a的平方转换为字符串,存入rs*/
函数myitoa(int num,char划的功能是将整数num转换为字符s,这就需要将整数num的每个数字分离出来,通常通过整除取余运算实现,即以下代码所实现的。
while (num) (/*从个位数开始,取num的每一位数字转换为字符后放入s[] */
s[n++] = (3) + '0';
num = num/10;
}
s[n]='\0';
其中,空(3)处应填入"num%10" 或其等价形式。
函数right(char*ms,int length)取字符串ms尾部长度为lenth的子串,返回所得子串的首字符指针。该函数的处理思路是先技到ms中字符串的结尾,然后倒着数出length个字符,从而得到所需字符串的首字符指计。空(5)处应填入"i++,ms--” 或其等价形式。
另一个更简便的方式是在得到ms的结尾指针后,再减去length即可,即最后返回ms-lenth即可。 ### 第 5 题
【说明】
某应急交通控制系统(TraficControlSystem)在红灯时控制各类车辆 (Vehicle)的通行,其类图如图5-1所示,在紧急状态下应急车辆在红灯时可通行,其余车辆按正常规则通行。
下面的C++代码实现以上设计,请完善其中的空缺。
【C++代码】
#include <typeinfo>
#include <iostream>
using namespace std;
class Vehicle { /*抽象基类,车辆*/
public:
virtual void run( ) = 0;
};
class Emergency { /*抽象基类,可在红灯时通行的接口,函数均为纯虚函数*/
public:
(1) = 0; // isEmergent ( )函数接口
};
class Car: public Vehicle {
public:
~Car ( ) { }
void run ( ) { /*代码略*/}
};
class Truck: public Vehicle {
public:
~Truck( ) { }
void run ( ) { /*代码略*/ }
};
class PoliceCar: (3) {
private:
bool isEmergency;
public:
PoliceCar( ) : Car( ) ,Emergency( ){ this->isEmergency = false;
}
PoliceCar(bool b) : Car( ) ,Emergency( ) { this->isEmergency = b;}
~policeCar ( ) { }
bool isEmergent ( ) { return (4) ; }
void runRedLight( ) { /*代码略*/ }
};
/*类Ambulance、 FireEngine 实现代码略*/
class TraficControlSystern { /*交通控制类*/
private:
Vehicle* v[24}; int nurnVeh:cles; /*在构造函数中设置初始值为0*/
public:
void control() { //控制在紧急情况下应急车辆红灯通行,其他情况按常规通行
for (int i = 0; i < numVehicles ; i++) {
Emergency * ev = dynamic_cast<Emergency*>(v[i]);
if (ev != 0) (5) ->runRedLight () ;
else (6) ->run () ;
}
}
void add(Vehicle * vehicle) { v[numVehicles++] = vehicle;
/ *添加车辆./
void shutDown() { for (int i = 0; i < numVehicles; i++) { delete
v[i]; } }
} ;
int main( ) {
TraficControlSystern. tcs = new TraficControlSystern;
tcs->add(new Car( )); tcs->add(new PoliceCar( ));
tcs->add(new Ambulance( ));tcs->add(new Ambulance(true));
tcs->add(new FireEngine(true)); tcs->add(new FireEngine( ));
tcs->add(new Truck( ));
tcs->control( ); tcs->shutDown( );
delete tcs;
} **答案与解析** - 试题难度:较难 - 知识点:C++程序设计>C++程序设计 - 试题答案:(1) virtual bool isEmergent()
(2)virtual void runRedLight()
(3) public Car,public Emergency
(4)this->isEmergency
(5) ev
(6)v[i]
- 试题解析:本题考查 C++语言程序设计的能力,涉及类、对象、函数的定义和相关操作。要求 考生根据给出的案例和执行过程说明,认;王阅读理清程序思路,然后完成题目。
根据题目描述,以交通控制系统(TraficControlSystem)为背景,本题目中涉及的各类车辆和是否应急状态下在红灯时的通行情况。根据说明进行设计,题目给出了类图(图5-1类图所示)。
图中父类Vehicle代表交通工具,设计为抽象类,包含一个方法: run(),表示行驶某一个具体的交通工具对象,行驶的方法由具体子类型完成,所以Vehicle的run()为一个纯虚函数:
virtual void run() = 0;
Car和Truck都继承自Vehicle的两个子类型,所以它们都继承了Vehicle的run()方法,各自行驶方式有所不同,所以都覆盖了vehicle的run()方法,并加以实现:
void run () {/*代码略*/}
Car的两个子类型PoliceCar和Ambulance都继承自Car,从而PoliceCar和Ambu1ance也都继承了Car中的run()方法。Truck的子类FireEngine也继承了Truck中的run()方法。
图中接口Emergency在C++中采用抽象茬类的方法实现,其中约定红灯时通行的相关接口函数为: isEmergent()和runRedLight() ,均为纯虚函数,原型中=0表示纯虚函数,实现由子类完成:
virtual bool isEmergent() = 0;
virtual void runRedLight() = 0;
isEmergent()函数接口约定应急车辆返回自身紧急情况状态,用bool类型的isEmergency 表示: this->isEmergency,其值在紧急情况下为bool值true ,非紧急情况下为bool值 false。runRedLight()函数接口约定应急车辆在红灯时如何通行(isEmergency为剧。则通行,isEmergency为false,和博通车辆一样通行)。 Emergency的子类有PoliceCar 、Abmulance和FireEngine,所以在这三个类中都要实现Emergency中定义的纯虚函数接口。
交通控制类TraficControlSystem对运轩的交通工具进行控制,所有交通工具用Vehicle数组v表示; numVehicles表示交通工具数量; control函数进行控制在紧急情况下应急车辆红灯通行,其他情况按常规通行; add()表示有车辆加入系统,shutDown()在系统关闭时清除每个对象数组元素: delete v[];。Vehicle的子类具体类型有Car、Truck、PoliceCar 、Abmulance和FireEngine,所以飞口数组中对象有这些类型的对象加入v[]时会自动向上转型成为Vehicle类型,而实现了Emergency接口的应急车辆有runRedLight()函数,其他 Car和Truck只有run()函数。因此,用for循环对每个v[i],判定是否是Emergency类型,即是否继承了Emergency ,调用时动态绑定每个数组元素的实际类型,需要通过动态类型转换:
Emergency * ev = dynamic_cast<Emergency*>(v[i]);
如果转换成功,说明是Emergency的子类,实现runRedLight(),可以调用runeRdLight(), 否则调用 run():
if (ev != 0) ev ->runRedLigh '. ();
else v [i]->run () ;
主控逻辑代码在main函数中实现。初始化TraficControlSystem,用tcs表示,调用tcs的add()函数添加具体的交通工具,这里告自动向上转型成为Vehicle类型,调用control()对各车辆进行控制,调用shutDown()系统关闭,使用完数组对象之后,需要用delete操作进行释放对象,即deletetcs;
因此,空(1)和空(2)需要定义纯盘函数isEmergency()和runRedLight(),原型中=0题目代码中己经给出,所以空(1)和空(2)分别为"virtual bool isEmergent()" 和"virtual void runRedLight()";空(3)需要继承Car和Emergency,即"public Car,public Emergency"; 空(4)要返回应急车辆对象的状态,即"this->isEmergency";空(5)处动态类型转换成功的对象ev; 空(6)处为普通车辆对象v[i]。 ### 第 6 题
阅读以下说明和Java代码,填充程序中的空缺,将解答填入答题纸的对应栏内。
【说明】
某应急交通控制系统(TraficControlSystem)在红灯时控制各类车辆 (Vehicle)的通行,其类图如图6-1所示,在紧急状态下应急车辆在红灯时可通行,其余车辆按正常规则通行。
下面的Java代码实现以上设计,请完善其中的空缺。
【Java 代码 】
abstract class Vehicle {
public Vehicle( ) { }
abstract void run( );
};
interface Emergency {
(1) ;
(2) ;
};
class Car extends Vehicle {
public Car( ) { )
void run ( ) { /代码略/ }
};
class Truck extends Vehicle {
public Truck( ) { }
void run ( ) { /代码略/ }
};
class PoliceCar (3) {
boolean isEmergency = false;
public PoliceCar() { }
public PoliceCar(boolean b) { this.isEmergency=b; }
public boolean isEmergent( ) { return ( 4 ) ; }
public void runRedLight( ) { /代码略/ }
};
/类Ambulance 、 FireEngine 实现代码略/
public class TraficControlSystem { /交通控制类/
private Vehicle[ ] v = new Vehicle[24];
int numVehicles;
public void control( ) {
for (int i = 0; i < numVehicles; i++) {
if (v[i] instanceof EmErgency && ((Emergency)v[i]).
isEmergent()) {
( 5 ) .runRedLigh ( );
} else
( 6 ) .run ( ) ;
}
}
void add(Vehicle vehicle) { v[numVehicles++] = vehiclei} /添加车辆/
void shutDown() { /代码略 /}
public static void main (Str :.ng [ ] args) {
TraficControlSystem tcs = new TraficControlSystem();
tcs.add(new Car()};
tcs.add(new PoliceCar();
tcs.add(new Ambulance();
tcs.add(new Ambulance(t:ue));
tcs.add(new FireEngine( :rue));
tcs.add(new Truck());
tcs.add(new FireEngine( );
tcs.control();
tcs.shutDown();
}
}
答案与解析
- 试题难度:较难
- 知识点:Java程序设计>Java程序设计案例
- 试题答案:(1) boolean isEmergent()
(2) void runRedLight()
(3)extends Car implements Emergency
(4) this.isEmergency
(5) (Emergency)v[i]
(6) v[i] - 试题解析:本题考查Java语言程序设计的能力,涉及类、对象、方法的定义和相关操作。要求考生根据给出的案例和执行过程说明,认真阅读理清程序思路,然后完成题目。
根据题目说明,以交通控制系统 (Tn .ficControlSystem) 为背景,本题目中涉及的各类车辆和是否应急状态下在红灯时的通行情况。根据说明进行设计,题目给出了类图(图6-1 类图所示)。
图中父类Vehicle ,代表交通工具,设计为抽象类。在Java用abstract 关键字表示, 表示行驶某一个具体的交通工具。 Vehiclt 包含一个抽象方法: run(),方法后没有实现, 直接用;来表示抽象方法,表示行驶的方法由具体子类型完成,所以Vehicle的 run()为一 个抽象方法:
abstract void run();
Car和Truck 都继承自 Vehicle 的两个子类型,所以他们都继承了Vehicle的 run()方法,各自行驶方式有所不同,所以都覆盖了 Vehicle 的 run()方法,并加以实现:
void run () U代码略/}
Car的两个子类型 PoliceCar 和Ambuance 都继承自 Car ,从而PoliceCar 和Ambulance 也都继承了 Car 中的 run( )方法。 Truck 的子类 FireEngine 也继承了 Truck 的 run()方法。
图 6-1 中 Emergency 在 Java 中采用技口实现,其中约定红灯时通行的相关接口为:
isEmergent()和runRedLight() 。
isEmergent()接口约定应急车辆返回 11身紧急情况状态,用 bool 类型的 isEmergency
表示:this.isEmergency ,其值在紧急情况下为true ,非紧急情况下为fales。runRedLight() 接口约定应急车辆在红灯时如何通行( isEmergency 为 true ,则通行,isEmergency 为 false , 和普通车辆一样通行)。实现 Emergency 的类商 PoliceCar、Abmulance 和 FireEngine ,所以在这三个类中都要实现 Emergency 中定义的接口。在 Java 中,实现接口用 implements 关键字,后面加上所要实现的接口,即:
. ClassName implements InterfaceName
交通控制类 TraficControlSystem 对运俨的交通工具进行控制,所有交通工具用 Vehicle 数组 v 表示; numVehicles 表示交通工具数量; control 函数进行控制在紧急情况 下应急车辆红灯通行,其他情况按常规通行; add()表示有车辆加入系统, shutDown()表 示系统关闭。 Vehicle 的子类具体类型有 Car、Tluck、PoliceCar、Abmulance 和 FireEngine , 所以 v[ ]数组中对象有这些类型的对象,加入 v[]时会自动向上转型成为 Vehicle 类型, Emergency 接口的应急车辆有 runRedLight01.法,其他 Car 和 Truck 只有 run()方法。因 此,用 for 循环中对每个 v[i] ,判定是否是Emergency 类型的实例,即是否实现了 Emergency。Java 中判断一个对象是否是某个类型的实例用 instanceof 关键字。即: v[i] instanceof Emergency ,如果是,说明是应急车辆,接着判定应急车辆的状态,在判定之 前先要将应急车辆进行向下转型, Java 中向下转型直接在对象前加上用括号括起来的转 换的目标类型即可,即: ((Emergency)vl[i]).isEmergent(), 如果判定为真,执行 runRedLight() ,判定不成功,则调用run() ,问用时动态绑定每个数组元素的实际类型, 需要通过动态类型转换并调用runR edLight():
if (v[i] instanceof Emergency && ((Emergency)v[i)) .isEmergent()) { ((Emergency)v[i]) .runRedLight( );
) else
v [i]->run () ;
主控逻辑代码在 mam 方法中实现。初始化 TraficControlSystem ,用tcs 表示,调用 tcs 的add()函数添加具体的交通工具,这里会自动向上转型成为Vehicle 类型,调用 control()对各车辆进行控制,调用 shutDown()系统关问。
因此,空(1)和空(2)需要定义接口sEmergentO和runRedLight() ,题目代码中 己经给出用分号结尾,所以空(1)和空(2)分别为 “bool isEmergent()” 和 “void runRedLight()”;空(3)需要继承父类 Car 和实现接口 Emergency ,Java 中继承采用extends关键字,即应填入“extends Car implements Emergency ”:空(4)要返回应急车辆对象的状态,即填入“this.isEmergency”;空 (5) 处为动态类型转换后的对象 (Emergency)v[i]; 空 (6)处为普通车辆对象 v[i] 。