java程序设计实用教程第版课后答案
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第一章
1.Java具有那些适合在Internet环境中的特点?
【答】简单性和完全面向对象,平台无关性,安全性和可靠性,多线程,高效的网络编程。
2.Java保留、放弃了C/C++语言中哪些语法和面向对象机制?为什么需要这样做?【答】在语法规则方面,Java语言放弃了全程变量、goto语句、宏定义、全局函数以及结构、联合和指针数据类型,使Java语言更简单、更精练。
在面向对象概念方面,Java语言放弃了多元继承、友元类和运算符重载,采用“单重继承+接口”的方式代替多重继承,提供语言级的内存自动管理和异常处理方式,使Java 语言更健壮、更安全、更高效。
3.Java对原程序文件的命名规则有什么要求?源程序文件编译后生成什么文件?
【答】要求:源程序文件与类同名,文件扩展名为.java;编译后生成字节码文件(*.class)。
4.Java程序的运行机制是怎样的?与C++或其他语言有什么不同?
【答】Java的每一个类都有一个class文件和它对应,Java在程序的启动的时候将程序运行需要用到的类加载到虚拟机中,根据Java的虚拟机规范进行连接(动态连接),程序的组装是在运行的时候完成的
C++和其他的编译型的语言一样,它的程序的组装方式是一种传统的组装方式。
C++在编译的时候生成适用于某一平台的二进制代码,在连接的时候找到需要调用的库,然后将这些库中的代码连接进可执行程序之中,生成的可执行程序运行速度非常的快,但是可执行代码已经变成了一个整体,不可能再分开
5.什么是平台无关性?Java是怎样实现平台无关性的?
【答】平台无关性即Java程序的运行不依赖于操作系统。
Java采用虚拟机技术实现平台无关性。
程序由虚拟机解释执行,不同的操作系统上运行不同版本的Java虚拟机。
6.Java应用程序由哪两种形式?他们的运行方式有什么不同?
【答】Application和applet两种形式,其中application是能够独立运行的应用程序,既可以以DOS的命令方式运行,也可以以图形用户界面方式运行。
Applet是可以嵌入页面的最小应用程序,不能独立运行,必须嵌入超文本中,由浏览器显示运行。
7.什么是解释执行?Java怎样解释执行两种应用程序?
【答】解释执行即将字节码解释成本地机器码并执行。
Java源程序文件经编译后生成字节码文件,若是application应用程序,则将字节码文件交由Java解释器解释执行,最后在windows操作系统上运行。
若是applet应用程序,则将字节码文件嵌入超文本文件并下载到web浏览器上,最后由windows操作系统中的Java 虚拟机运行。
8.作为一个软件开发人员,应该具备那些基础知识用以开发windows应用程序?
【答】略
第2章
1.标示符和关键字在定义和使用方面有何区别?
【答】定义方面:标示符是用户定义的、以字母开头的字母数字序列,关键字是由Java语言定义的、具有特定含义的英文单词。
使用方面:标示符用于命名变量、常量、类、对象等元素,每一个关键字都有特定的含义,不能被赋予别的含义。
2.Java语言的基本数据类型有哪些?引用数据类型有哪些?
【答】基本数据类型有:整数类型byte、short、int、long,浮点数类型float、double,字符类型char,布尔类型boolean;引用数据类型包括数组(array)、类(class)和接口(interface)
3.试分析基本数据类型与引用数据类型的主要特点,并说明使用这两种变量有哪些差别?【答】基本数据类型的变量保存数据值,而引用数据类型的变量保存地址。
4.算术运算、关系运算、逻辑运算和位运算各有哪些运算符?
【答】算术运算:单目运算符有+(正)、—(负)、++(自增)、——(自减),双目运算符有+(加)、—(减)、*(乘)、/(除)、%(取余)
关系运算:=(等于)、!=(不等于)、>(大于)、<(小于)、>=(大于等于)、<=(小于等于)都是双目运算
逻辑运算:&(与)、|(或)、!(非)、^(异或)、&&(条件与)、||(条件或),其中!是单目运算,其它都是双目运算
位运算:~(非)、&(与)、|(或)、^(异或)、<<(左移位)、>>(右移位)、>>>(无符号移位)
5.程序中为什么需要常量和变量?声明常量或变量时,为什么必须给出其所属的数据类型?
【答】在程序中使用的数据大多需要经常变化,用常量值表示显然不够,因此每一种算法语言都提供常量和变量来存储数据。
为了确定常量或变量的数据性质、取值范围、以及它们占用的内存单元的字节数和它们参加的合法运算和操作。
6.什么是变量的作用域,声明变量时,如何确定变量的作用域?
【答】变量的作用域是指其作用范围。
变量声明的位置决定了它的作用域
7.设i是一个整数类型变量,写出下列问题对应的表达式?
(1)判断i为奇数或偶数;
【答】i%2==0 //取值为true时是偶数,否则是奇数
(2)判断i的值是否在0~9之间;
【答】(i>0)&&(i<9)
8.设ch是一个字符变量,写出下列问题对应的表达式
(1)判断ch是一个十进制的数字字符
(2)判断ch是一个十六进制的数字字符
(3)判断ch是一个大写字母
(4)判断ch是一个英文字母,不论大写和小写
(5)如何将一个十进制的数字字符ch转换成对应的整数类型值
(6)如何将一个十六进制的数字字符ch转换成对应的整数类型值
9.说明for、while、和do-while三种循环语句的特点和区别?
While语句的特点:“先判断后执行”,当条件满足时执行循环体
Do-while语句的特点:“先执行后判断”,先执行循环体,再判断条件是否满足
For语句的特点:“先判断后执行”,但for语句将循环控制变量初始值、循环条件和变量的变化规律都以表达式形式写在循环体之前。
10.分别用for,while,do-while三种循环语句计算一个正数的阶乘
(1)for(i=1,i<=10,i++){
int Sum=1;
Sum=Sum*i;} \\等价于Sum*=i;
(2)int i=1;
while(i<=10){
int Sum=1;
Sum=Sum*i;
i++;}
int i=Sum=1;
do{
Sum=Sum*i;
i++;}while(i<=10);
11.输出以下数字的形式;
(1) 0 0 0 0
0 1 1 1
0 1 2 2
0 1 2 3
〖解答〗采用二重循环的程序如下。
public class Phalanx
{
public static void main(String args[])
{
int n=4; //阶数 for (int i=0;i<n;i++)
for (int j=0;j<n;j++)
}
}
}
(2)输出下列形式的数字三角阵(当n=4时)。
1
1 2 1
1 2 3 2 1
1 2 3 4 3 2 1
〖解答〗采用二重循环的程序如下。
public class Tower
{
public static void main(String args[])
{
int n=4; //行数 for (int i=1;i<=n;i++)
for (int j=1;j<=n-i;j++) //前导空格
for (int j=1;j<=i;j++)
for (int j=i-1;j>0;j--)
}
}
}
12.下列程序希望用for语句求出1~n累加和并显示,请问程序有错误吗?错在哪里?输出结果i和s的值分别是多少?
int i=1,n=10,s=0;
for(i=1,i<=n,i++);
s+=i;
“Sum=1+……+”+n+”=”+s);
有错误,正确的如下
int i=1,n=10,s=0;
for(i=1,i<=n,i++)
s+=i;
“Sum=1+……+”+n+”=”+s);
13.编程验证哥德巴赫猜想。
哥德巴赫猜想:
(1)任何大于2的偶数都可以表示为2个素数之和,如16=3+13,16=5+11
(2)任何大于5的奇数都可以表示为3个素数之和,如11=2+2+7,11=3+3+5
〖解答〗程序如下。
public class Goldbach
{
static final int MAX=30; //数据范围
static int[] prime=null; //存放素数的一维数组
static int number; //素数个数,即数组的实际元素个数
public Goldbach(int n) //输出n的哥德巴赫算式
{
if (prime==null)
init();
if (n%2==0) //偶数
{
int i=0;
while (i<number && prime[i]<=n/2)
{
if (isPrime(n-prime[i]))
i++;
}
}
else //奇数
{
int i=0;
while (i<number && prime[i]<=n/3)
{
int j=i; //如果j=0,则会出现重复的算式 while (j<number && prime[j]<=n/3)
{
if (isPrime(n-prime[i]-prime[j]))
+(n-prime[i]-prime[j])+" ");
j++;
}
i++;
}
}
}
public static void init() //初始化数组,筛选法求素数
{
prime = new int[30];
prime[0]=2; //已知的最小素数
number=1; //素数个数
int i=1; //下一个素数应存放的数组下标位置 int k=3; //从最小奇数开始测试,所有偶数不需测试
do
{
int j=0;
while ((j<number) && (k % prime[j]!=0)) //用已知素数prime[j]测试k
j++;
if (j==number) //k是素数
{
prime[i]=k; //将k添加到数组prime 中
i++;
number++;
}
k+=2; //测试下一个奇数是否是素数
} while(k<MAX);
output();
}
public static void output() //输出素数
{
for (int i=0;i<number;i++)
{
if ((i+1)%10==0)
//每行写10个数
}
}
public static boolean isPrime(int k) //判断k是否为素数,即在prime 中查找k值
{
boolean yes=false;
int i=0;
while (!yes && i<=number && prime[i]<=k)
if (prime[i]==k)
yes=true;
else i++;
return yes;
}
public static void main(String args[]) {
for(int i=4;i<Goldbach.MAX;i+=2)
new Goldbach(i);
for(int i=7;i<Goldbach.MAX;i+=2)
new Goldbach(i);
}
}
程序运行结果如下:
All primes in 2~30 are:
2 3 5 7 11 13 17 19 23 29 number=10
偶数
4=2+2
6=3+3
8=3+5
10=3+7 10=5+5
12=5+7
14=3+11 14=7+7
16=3+13 16=5+11
18=5+13 18=7+11
20=3+17 20=7+13
22=3+19 22=5+17 22=11+11 24=5+19 24=7+17 24=11+13 26=3+23 26=7+19 26=13+13 28=5+23 28=11+17
奇数
7=2+2+3
9=2+2+5 9=3+3+3
11=2+2+7 11=3+3+5
13=3+3+7
15=2+2+11 15=3+5+7 15=5+5+5 17=2+2+13 17=3+3+11 17=5+5+7 19=3+3+13 19=3+5+11
21=2+2+17 21=3+5+13 21=3+7+11 21=5+5+11 21=7+7+7
23=2+2+19 23=3+3+17 23=3+7+13 23=5+5+13 23=5+7+11
25=3+3+19 25=3+5+17 25=5+7+13 25=7+7+11
27=2+2+23 27=3+5+19 27=3+7+17 27=5+5+17 27=7+7+13
29=3+3+23 29=3+7+19 29=5+5+19 29=5+7+17
不能有重复表达式,例如
19=3+3+13 19=3+5+11 19=5+3+11
21=2+2+17 21=3+5+13 21=3+7+11 21=5+3+13 21=5+5+11 21=7+3+11 21=7+7+7
14.Java的数组比C++的数组有哪些优越之处?
【答】Java语言不支持C++的指针类型,对数组的操作只能按照数组方式,不能使用指针。
Java的数组都是动态数组,并且是引用数据类型,提高了安全性和简单性。
另外,Java语
言具有资源回收机制,能够自动收回不再使用的资源,一般情况下程序不需要归还数组所
占的内存空间。
15.作为引用数据类型,数组变量与基本数据类型的变量使用时有哪些区别?
【答】数组变量与基本数据类型变量不同点在于,存储单元的分配方式不同,两个变量之
间的赋值方式也不同。
基本数据类型变量获得存储单元的方式是静态的,声明了变量后系
统就为变量分配了存储单元,就可以对变量赋值。
两个变量之间的赋值是值本身。
数组变量的引用赋值,数组变量保存的是数组的引用,即数组占用的一片连续存储空
间的首地址及长度特性。
当声明一个数字变量而未申请空间时,变量是未初始化的,没有地址及特性值。
只有申请了存储空间,才能以下标表示数组元素。
16.求一组数中的最大值和最小值。
【答】程序如下:
public class Zuizhi {
public static void main(String[] args)
{
// TODO 自动生成方法存根
int array[]=new int[100];
for(int i=1;i<=30;++i)//初始化数组
array[i]=i;
int max=array[1];//保存最大值
int min=array[1];//保存最小值
for(int j=2;j<=30;++j)
{
max=Math.max(max, array[j]);
min=Math.min(min, array[j]);
}
该数组最大值为:"+max);
该数组最小值为:"+min);
}
}
运行结果如下:
该数组最大值为:30
该数组最小值为:1
17.采用一维数组输出杨辉三角形。
程序如下:
public class Yanghui1
{
public static void main(String args[])
{
int n=10; //n表示行数
int[] table = new int[n+1];
table[0]=1; //每行第1个数都为1
for (int i=1;i<=n;i++) //控制输出n行
{
for (int j=0;j<i;j++) //输出三角形的一维数组 for (int j=i;j>0;j--) //生成下一行数据 table[j]=table[j-1]+table[j]; //通式
}
}
}
18.输出下列方阵:
(1) 输出如下形式的数字方阵(当n=4时):
1 2 6 7
3 5 8 13
4 9 12 14
10 11 15 16
程序如下:
Public class Jmat
{
Public static void main(String args[]){
}
}
(2)输出如下形式的数字方阵(当n=4时):
1 2 5 10
4 3 6 11
9 8 7 12
16 15 14 13
〖解答〗采用二维数组的程序如下。
public class Jmat
{
public static void main(String args[])
{
int n=4; //阶数
int[][] mat = new int[n][n];
int k=1; //k是自然数,递增变化 for (int i=0;i<n;i++)
{
for (int j=0;j<=i;j++)
mat[j][i] = k++; //k先赋值后自加
for (int j=i-1;j>=0;j--)
mat[i][j] = k++;
}
for (int i=0;i<mat.length;i++) //输出二维数组元素 {
for (int j=0;j<mat[i].length;j++) //i、j是行、列下标 }
}
}
19.找出一个二维数组的鞍点,即该位置的元素在该行上最大,在列上最小。
也可能没有暗点。
〖命题〗一个二维数组如果有鞍点,那么它只有一个鞍点。
〖证明〗反证法。
设该二维数组已有一个鞍点,为M[i,j],则有
M[i,*] <= M[i,j] <= M[*,j] (1)
即i行上的所有元素均小于j列上的所有元素。
假设有另一个鞍点M[x,y],由(1)式知
M[i,y] <= M[x,j] (2)
而M[x,y]应在该行上最大,有
M[x,y] >= M[x,j] (3)
M[x,y]应在该列上最小,有
M[x,y] <= M[i,y] (4)
根据(2)式,显然(3)和(4)式是不可能同时成立的。
因而假设有另一个鞍点M[x,y]是不成立的。
由此证明。
〖解答〗采用二维数组的程序如下。
public class Dort
{
public static void main(String args[])
{
int[][] mat = {{1,2,3},{4,5,6},{7,8,9}};
for (int i=0;i<mat.length;i++) //输出二维
数组元素
{
for (int j=0;j<mat[i].length;j++) //i、j是行、
列下标
}
boolean find = false; //找到鞍点
标记
int row=0; //第1行下标
int max=0; //记录当前行最
大值的列下标
while (!find && row<mat.length)
{
max=0; //初始设每行第1
列值最大
for (int j=1;j<mat[row].length;j++) //在row行上
找最大值
if (mat[row][j]>mat[row][max]) //mat[row][max]为该行最大值
max = j;
boolean yes = true; //再判断mat[row][max]是否在列上最小
int j=0;
while (yes && j<mat.length)
{
if (j!=row && mat[j][max]<mat[row][max]) //在列上找到更小值,则不是鞍点
yes = false;
j++;
}
if (yes)
find = true;
else
row++;
}
if (find)
else
}
20.设一个一维数组的元素值为:7,4,8,9,1和5,请输出具有以下内容的方阵:
7 4 8 9 1 5
57 4 8 9 1
1 5 7 4 8 9
9 1 5 7 4 8
8 9 1 5 7 4
4 8 9 1
5 7
【答】程序如下:
public class Shift
{
public static void main(String args[])
{
int table[] = {7,4,8,9,1,5};
for (int i=0;i<table.length;i++)
{
for (int j=0;j<table.length;j++)
}
for (int i=0;i<table.length;i++) {
int j=i;
do
{
j=(j+1)%table.length;
}while (j!=i);
}
}
}
第3章面向对象的核心特征
3-1 什么是类?什么是对象?他们之间的关系是怎样的?
【答】在面向对象的概念中,类是既包括数据又包括作用于数据的一组操作的封装体。
类中的数据称为成员变量,类中的数据操作称为成员方法。
类中的成员变量和成员方法统称为类的成员。
对象是类的实例。
对象与类的关系就像变量与数据类型的关系一样。
是抽象与具体,模板与实例的关系,类是抽象的、是模板,对象是具体的、是实例。
3-2 作为引用数据类型,对象在赋值和方法的参数传递方面与基本数据类型的变量有什么不同?
【答】作为引用数据类型,两个对象之间的赋值是引用赋值,对象可被赋值为null。
具体可参见课本第三章图3.1的(d)。
方法声明中形式参数的数据类型,既可以是基本数据类型,也可以是引用数据类型。
如果形式参数的数据类型是基本数据类型,则实际参数向形式参数传递的是值;如果形参的数据类型是引用数据类型,则实参向形参传递的是引用。
同样,方法返回值的数据类型,既可以是基本数据类型,也可以是引用数据类型,两者分别传递值和引用。
3-3 面向对象技术的三个核心特性是什么?
【答】类的封装、继承和多态。
3-4 什么是封装?为什么要将类封装起来?封装的原则是什么?
【答】封装性是面向对象的核心特征之一,它提供一种信息隐藏技术。
类的封装包含两层含义:一是将数据和对数据的操作组合起来构成类,类是一个不可分割的独立单位;二是类中既要提供与外部联系的方法,同时又要尽可能隐藏类的实现细节。
软件扩充和维护的需要需对类进行封装。
封装原则:隐藏内部实现细节。
3-5 类中的方法与C++中的函数有什么差别?
【答】Java类中的成员方法与C语言中的函数很像,但在声明、调用等方面存在很大差别。
具体方法可参考课本P66~P67。
3-6 类的构造方法和析构方法有什么作用?它们分别被谁调用?它们的访问权限范围应该是怎样的?是否每个类都必须设计构造方法和析构方法?没有设计构造方法和析构方法的类执行什么构造方法和析构方法?
【答】类的构造方法和析构方法是类特殊的成员方法,构造方法用于在创建实例时进行初始化;析构方法用于在释放实例时执行特定操作。
构造方法由new运算符调用;析构方法可由对象调用,或被虚拟机自动执行。
它们的访问权限范围通常都是public。
构造方法不能继承,析构方法能够继承。
一个类可以不声明构造方法和析构方法。
当一个类没有声明构造方法时,Java为它提供一个无参数的默认构造方法,约定自动调用父类的默认构造方法(无参数);当一个类没有声明析构方法时,它执行继承来的父类的析构方法。
3-7 Java定义了几个关键字用于表示几种访问权限?各表示什么含义?类有几种访问权限?类中成员有几种访问权限?分别使用什么关键字?
【答】Java定义了三个表示权限的关键字(public、protected、private)。
类有2种访问权限分别是:公有public,缺省。
类中成员有4种访问权限分别是:公有public,可被所有类访问;保护protected,可被同一包及包外所有子类访问;缺省,可被当前包中所
有类访问;私有private,只能被当前类访问。
3-8 this引用有什么作用?this引用有几种使用方法?
【答】Java类中成员方法与C语言中函数还有一个重要差别就是,Java类中每个成员方法都可以使用代词this引用调用该方法的当前对象自己,this引用有以下3种用法:(1)this用于指代调用成员方法的当前对象自身,语法格式如下:
this
(2)通过this可以调用当前对象的成员变量,调用当前对象的成员方法。
语法格式如下:
this.成员变量
this.成员方法([参数列表])注意:Java中的this是引用方式,不是C++中的指针方式。
(3)this引用还可以用在重载的构造方法中,调用本类已定义好的构造方法。
语法格式如下:
this([参数列表])注意:在构造方法中,this()引用必须是第一行语句。
3-9 说明类成员与实例成员的区别。
【答】Java的类中可以包括两种成员:实例成员和类成员。
实例成员是属于对象的,实例成员包括实例成员变量和实例成员方法。
类成员是属于类的,需要用关键字static标识,也称为静态成员。
具体区别如下:
1.实例成员变量与类成员变量
(1) 两者声明时的差别。
当一个类声明成员变量时,没有使用关键字static声明的为实例成员变量,使用关键字static声明的为类成员变量。
(2) 两者存储结构的差别。
当创建一个对象时,系统会为每一个对象的每一个实例成员变量分配一个存储单元,使得属于不同对象的实例成员变量有不同的值;而为每一个类成员变量只分配一个存储单元,使得所有对象公用一个类成员变量。
(3) 两者引用方式的差别。
实例成员变量属于对象,必须通过对象访问;类成员变量属于类,既可以通过对象,也可以通过类访问。
2.实例成员方法与类成员方法
(1) 两者声明时的差别。
当一个类声明成员方法时,没有使用关键字static声明的为实例成员方法,使用关键字static声明的为类成员方法。
(2) 两者方法体中语句的差别。
类成员方法只能访问类成员变量;实例成员方法既可以访问类成员变量,也可以访问实例成员变量。
在实例成员方法体中,可以使用this引用指代当前对象;而在类成员方法体中,则不能使用this引用。
(3) 两者引用方式的差别。
实例成员方法必须通过对象访问;类成员方法既可以通过对象,也可以通过类访问。
3-10 什么是继承?继承机制的作用是什么?子类继承了父类中的什么?子类不需要父类中的成员时怎么办?能够删除它们吗?Java允许一个类有多个父类吗?
【答】继承性是面向对象的核心特征之一,是一种由已有的类创建新类的机制。
被继承的类称为父类或超类,通过继承产生的新类称为子类或派生类。
继承机制是面向对象程序设
计中实现软件可重用性的最重要手段。
通过继承,子类自动拥有父类的所有成员,包括成员变量和成员方法(不包括构造方法)。
子类可以更改父类成员,还可以增加自己的成员,但是,不能删除父类的成员。
在Java中以“单重继承+接口”的方式代替多重继承,不允许一个类有多个父类。
3-11 子类能够访问父类中什么样权限的成员?
【答】虽然子类继承了父类的成员变量和成员方法,但并不是对所有的成员都有访问权限。
访问权限说明如下:
(1)子类对父类的私有成员(private)没有访问权限。
(2)子类对父类的公有成员(public)和保护成员(protected)具有访问权限。
(3)子类对父类中缺省权限成员访问权限分为两种情况,对同一包中父类的缺省权限成员具有访问权限,而对不同包中父类的缺省权限成员没有访问权限。
3-12 如果子类声明的成员与父类成员同名会怎么样?
【答】如果子类重定义父类的同名成员变量,则子类隐藏了父类成员变量。
如果子类重定义父类的同名成员方法,当子类方法的参数列表与父类方法的参数列表完全相同时,则称子类成员方法覆盖了成员方法。
如果子类重定义父类的同名成员方法,当子类方法的参数列表与父类方法的参数列表不同时,子类继承了父类的成员方法,并重载了继承来的该成员方法。
3-13 super引用有什么作用?super引用有几种使用方法?
【答】当子类重定义了父类成员时,则存在同名成员问题。
此时,在子类方法体中,成员
均默认为子类成员。
如果需要引用父类同名成员,则需要使用supper引用。
在以下两种同名成员情况下,需要使用supper引用。
(1)子类隐藏父类成员时,如需要访问父类同名成员变量时,需要使用supper指代父类的同名成员变量。
语法如下:
super.成员变量
(2)子类覆盖父类成员时,如需要访问父类同名成员方法时,需要使用supper指代父类的同名成员方法。
语法如下:
super.成员方法([参数列表])
注意:super引用不能像this引用一样单独使用。
3-14 什么是多态性?什么是方法的重载?方法的重载和覆盖有何区别?
【答】在面向对象语言中,多态是指一个方法可以有多种实现版本,类的多态性表现为方法的多态性。
重载是指同一个类中的多个方法可以同名但参数列表必须不同。
重载表现为同一个类中方法的多态性。
覆盖是指子类重定义了父类中的同名方法。
覆盖表现为父类与子类之间方法的多态性。
3-15 什么是运行时多态?方法的重载和覆盖分别是什么时的多态性?
【答】如果在编译时不能确定、只有在运行时才能确定执行多个同名方法中的哪一个,则称为运行时多态。
方法的重载都是编译时多态。
方法的覆盖变现出两种多态性,当对象获得本类的实例时,为编译时多态,否则为运行时多态。
3-16 什么是抽象类?在什么情况下需要设计抽象类?抽象类中是否必须有抽象方法?
【答】使用关键字abstract声明的类称为抽象类,使用abstract声明的成员方法为抽象方法。
抽象类中可以不包含抽象方法,但包含抽象方法的类必须被声明为抽象类。
3-17 什么是最终类?在什么情况下需要设计最终类?最终类中是否必须有最终方法?【答】使用关键字final声明的类称为最终类,最终类不能被继承。
使用final声明的成员方法称为最终方法,最终方法不能被子类覆盖。
最终类中包含的都是最终方法,非最终类也可以包含最终方法。
3-18 将辗转相除法求两个整数的最大公因数gcd(a,b)用递归方法实现,辗转相除法题意见例2.11,再设计下列方法:
(1)求两个整数a﹑ b的最小公倍数;
(2)求三个整数a﹑b﹑c的最大公约数。
〖解答〗程序如下。
public class GCD_recursion
{
public static int gcd(int a,int b) //返回a,b的最大公因数
{
if (b==0)
return a;
if (a<0)
return gcd(-a,b);
if (b<0)
return gcd(a,-b);
return gcd(b, a%b);
}
public static int gcd(int a,int b,int c) //返回a,b,c的最大公因数
{
return gcd(gcd(a,b),c);
}
public static int multiple(int a,int b) //返回a,b的最小公倍数
{
return a*b/gcd(a,b);
}
public static void main(String args[])
{
int a=12,b=18,c=27;
}
}
程序运行结果如下:
gcd(12,18)=6
gcd(-12,18)=6
gcd(12,18,27)=3
multiple(12,18)=36
3-19 用递归方法求 n个数的无重复全排列。
〖解答〗程序如下。
public class Permutation
{
private int[] table;
public Permutation(int n) //构造方法
{
if (n>0)
{
table = new int[n];
for (int i=0;i<n;i++)
table[i] = i+1;
permute(n);
}
else
table = null;
}
private void output() //输出数组元素
{
for (int i=0;i<table.length;i++)
}
private void swap(int i,int j) //交换数组两个元素值
{
if (table!=null && i>=0 && i<table.length && j>=0 &&
j<table.length)
{
int temp = table[i];
table[i] = table[j];
table[j] = temp;
}
}
private void permute(int n) //用递归方法求n个数的无重复全排列
{
if (n==1)
this.output();
else
{
permute(n-1);
for (int j=0;j<n-1;j++)
{
swap(n-1,j);
permute(n-1);
swap(n-1,j);
}
}
}
public static void main(String args[]) {
new Permutation(3);
}
}
程序运行结果如下:
1 2 3
2 1 3
3 2 1
2 3 1
1 3 2
3 1 2
3-20 Java为什么不支持指针?C++的指针类型存在哪些潜在的错误?没有指针,Java如何实现在C++中用指针实现的功能?例如,通过访问指针访问数组元素,通过指针使用字符串,方法参数传递地址,方法参数用于输出,方法返回非基本数据类型等。
【答】由于指针往往在带来方便的同时也导致代码不安全的根源,如内存泄露等,同时也会使程序变得非常复杂难以理解,Java语言明确说明取消了指针。
Java使用引用代替了指针。
3-21 Java为什么不支持C++的运算符重载特性?
【答】这是为了防止运算符重载使得代码的功能变的不清晰。
第4章接口﹑内部类和包
4-1 什么是接口?接口和抽象类有哪些相同之处和不同之处?
【答】接口是一组常量和抽象方法的集合。
在Java中,接口是一种引用数据类型,用关键字implements声明。
接口与抽象类的区别为:
相同点:1.两者都包含抽象方法,约定多个类共用方法的参数列表和返回值。
2.两者都不能被实例化。
3.两者都是引用数据类型,其变量可被赋值为子类或实现接口类的对象。
不同点:1.抽象类约定多个子类之间共同使用的方法;接口约定多个互不相关类之间共同使用的方法。
2.抽象类与子类之间采用单重继承机制;一个类实现多个接口则实现了多重继承的功能。
3.抽象类及其类中成员具有与普通类一样的访问权限;接口的访问权限由public和缺省两种,接口中成员的访问权限均是public。
4.抽象类中可以包含非抽象方法,也可以声明构造方法;接口中的方法必须全部是抽象方法,不能声明构造方法。
5.抽象类中可以声明成员变量,子类可以对该成员变量赋值;接口中只能声明常量。
4-2 为什么能够声明接口变量?接口变量能够获得什么样的值?
【答】接口是引用数据类型可以声明接口变量。
接口变量能够获得实现接口的类的对象,也称为接口对象。
4-3 接口有哪些特点?为什么需要声明借口?接口是否具有继承性?接口中能否写构造方法?
【答】接口特点:
(1)接口及接口中成员的访问权限都是public。