Java之重点

先看点Java,免得日后夜长梦多,先秒了有精力做其他事情。

Java 开发与运行程序的步骤及过程

问题:开发与运行 Java 程序需要经过哪些主要步骤和过程?

答案:主要有三个步骤:

  1. 编写源文件
    • 使用文字编辑器(如 Notepad)或开发环境(如 Jcreator、Gel、BlueJ、Eclipse、Jbuilder 等)编写 Java 源文件(以 .java 作为扩展名)。
  2. 编译源文件
    • 使用 Java 编译器(如 javac.exe)将 Java 源文件编译成字节码文件(即 .class 文件)。该文件包含可以由 Java 虚拟机 (JVM) 运行的字节码。
  3. 运行程序
    • 对于应用程序,通过 Java 解释器(如 java.exe)来运行编译后的 .class 文件。
    • 对于小应用程序 (Applet),应通过支持 Java 标准的浏览器(如 Microsoft Explorer)来解释运行。

JDK 安装后如何设置 PATH 和 CLASSPATH 以及它们的作用

问题:安装 JDK 之后如何设置 JDK 系统的 PATH 和 CLASSPATH? 它们的作用是什么?

答案

  1. 设置 PATH:

    • PATH 用于告诉操作系统 Java 编译器 (javac.exe) 和 Java 解释器 (java.exe) 所在的路径。设置 PATH 后,可以在任意目录下执行 Java 命令。

    • 设置方法:对于 Windows 95/98,可以在 autoexec.bat 文件的最后一行添加:

      1
      SET PATH=C:\j2sdk1.4.2\bin;%PATH%
  2. 设置 CLASSPATH:

    • CLASSPATH 用于告诉 Java 运行时环境从哪些路径查找所需的类文件或库文件。一般用于查找用户类库或常用的第三方库。

    • 设置方法:可以在环境变量中设置 CLASSPATH,通常格式如下:

      1
      SET CLASSPATH=.;C:\j2sdk1.4.2\jre\lib\jaws.jar;%CLASSPATH%
      • . 表示当前工作目录,用于查找程序相关的类。

Java 语言的特点

问题:Java 语言的特点是什么?

答案:Java 语言具有以下特点:

  1. 简单:Java 语法简单,易学易用。
  2. 面向对象:Java 是一种面向对象的编程语言,强调类和对象的概念。
  3. 分布式:Java 支持分布式计算,提供丰富的网络库。
  4. 解释性:Java 程序是通过字节码运行在 JVM 上,具有解释性。
  5. 健壮性:Java 强调代码的健壮性,支持异常处理和自动垃圾回收。
  6. 安全性:Java 提供了严格的安全机制,特别是在网络环境下。
  7. 结构中立:Java 编译生成的字节码与平台无关,可以在不同平台上运行。
  8. 可移植性:Java 程序可以在任何支持 JVM 的设备上运行。
  9. 高性能:通过即时编译(JIT)和字节码优化,Java 可以实现较高的性能。
  10. 多线程:Java 原生支持多线程编程,便于开发并发应用。
  11. 动态性:Java 支持动态加载类和反射机制,具有良好的扩展性。

面向过程与面向对象编程的异同

问题:简述面向过程问题求解和面向对象问题求解的异同。试列举面向对象和面向过程的编程语言各两种。

答案

  1. 面向过程
    • 面向过程编程利用计算机能够理解的离散逻辑来描述和表达问题及其解决过程。它的核心是算法和数据结构,解决问题的方式是通过编写一系列步骤来完成任务。
  2. 面向对象
    • 面向对象编程通过模拟现实世界中的对象及其属性和行为来解决问题。它的核心是类、对象和设计模式,通过封装、继承和多态来组织程序。
  3. 异同
    • 相同点:两者都可以用于编写程序解决问题,最终目的是实现某种功能。
    • 不同点:面向过程强调的是过程和步骤,面向对象则强调数据和行为的结合。
  4. 编程语言
    • 面向过程的编程语言:BASIC、FORTRAN、Pascal、C。
    • 面向对象的编程语言:Smalltalk-80、Object Pascal、C++、Java。

1. 基本数据类型和引用数据类型的基本特点

问题:试分析基本数据类型和引用数据类型的基本特点?

答案

  1. 基本数据类型
    • Java 提供了 8 种基本数据类型,包括:
      • 整数类型:byte (1字节)、short (2字节)、int (4字节)、long (8字节)
      • 浮点数类型:float (4字节)、double (8字节)
      • 字符类型:char (2字节,基于 Unicode)
      • 布尔类型:boolean (1字节,表示 truefalse)
    • 这些类型有固定的大小,并且不受运行平台的变化而改变,这意味着无论在哪个平台上,数据类型的大小都是确定的。
  2. 引用数据类型
    • 引用数据类型包括接口数组枚举
    • 引用类型的变量存储的是对象的内存地址,而不是对象本身的数据。引用类型通过类或对象的实例化来实现。
    • 当引用类型的变量被分配时,它在堆内存中分配对象空间,指向该对象的内存地址。

2. 使用异或运算符实现两个整数的交换

问题:请使用异或运算符,实现两个整数的交换。

答案:异或运算符 ^ 可以用来交换两个整数的值,而不需要使用临时变量。以下是代码实现:

1
2
3
4
5
6
7
8
9
10
11
int x = 5;
int y = 19;

// 使用异或运算交换 x 和 y 的值
x = x ^ y; // 第一步:x 变为 x^y
y = y ^ x; // 第二步:y 变为 y^x^y,也就是 x
x = x ^ y; // 第三步:x 变为 x^y^x,也就是 y

// 输出交换后的值
System.out.println("x = " + x); // 输出: x = 19
System.out.println("y = " + y); // 输出: y = 5

通过异或运算可以实现两个整数值的交换,不使用第三个变量。


3. 标识符的合法性判断

问题:下列哪个是合法的标识符: B()
A、a=b
B、Hello
C、2nd
D、Chong qing

答案B (Hello) 是合法的标识符。

分析

  • 标识符是指在 Java 程序中用于命名变量、方法、类等的名字。合法的标识符必须遵循以下规则:
    • 标识符只能由字母数字下划线 (_) 和 美元符号 ($) 组成。
    • 标识符不能以数字开头。
    • 标识符不能是 Java 的关键字
    • 标识符不能包含空格和特殊符号(如 =& 等)。

选项分析

  • a=b 包含非法字符 =,不合法。
  • Hello 是合法的标识符。
  • 2nd 以数字开头,不合法。
  • Chong qing 包含空格,不合法。

4. 标识符的合法性判断(续)

问题:下列哪些是合法的标识符()。
A、new
B、class
C、int
D、const2

答案D (const2) 是合法的标识符。

分析

  • new 是 Java 的关键字,不合法。
  • class 是 Java 的关键字,不合法。
  • int 是 Java 的关键字,不合法。
  • const2 是合法的标识符,因为它由字母和数字组成,且不以数字开头,也不是 Java 的关键字。

5. 变量初始化问题

问题:如果定义有变量 double d1, d2 = 4.0;,则下列说法正确的是:

A、变量 d1, d2 均初始化为 4.0
B、变量 d1 没有初始化,d2 初始化为 4.0
C、变量 d1, d2 均未初始化
D、变量 d2 没有初始化,d1 初始化为 4.0

答案B,变量 d1 没有初始化,d2 初始化为 4.0。

分析

  • double d1, d2 = 4.0; 表示定义了两个 double 类型的变量:
    • 变量 d1 没有被初始化,它只是被声明。
    • 变量 d2 被初始化为 4.0
  • 在 Java 中,未初始化的局部变量不能被使用,必须在使用前进行显式初始化。

1. 变量初始化判断

问题:所有的变量在使用前都必须进行初始化。

答案正确

分析

  • 在 Java 中,局部变量必须在使用前进行显式初始化,否则编译器会报错。
  • 类的成员变量如果没有显式初始化,则会自动使用默认值(例如:整数默认值为 0,布尔值默认是 false,引用类型默认是 null)。

2. byte 数据类型的取值范围

问题:内部数据类型 byte 的取值范围是:

A、0-65,535
B、(-128)-127
C、(-32,768)-32,767
D、(-256)-(-255)

答案B(-128)-127

分析

  • byte 数据类型的取值范围是 8 位的有符号整数,范围为 -128127
  • 选项分析:
    • 选项 A 的范围适用于 char 类型。
    • 选项 C 的范围适用于 short 类型。
    • 选项 D 并不符合任何基本数据类型的取值范围。

3. 不能通过编译的语句

问题:下列哪些是不能通过编译的语句:

A、int i = 32;
B、float f = 45.0;
C、double d = 45.0;
D、char a = 'c';

答案B

分析

  • 选项 A (int i = 32;) 合法,int 类型可以直接赋值为整数。
  • 选项 B (float f = 45.0;) 不能通过编译,因为 45.0double 类型的字面值。要将其赋值给 float 变量,必须在数值后加上 f(如 45.0f),否则编译器会报错。
  • 选项 C (double d = 45.0;) 合法,double 类型的变量可以直接接受 double 类型的字面值。
  • 选项 D (char a = 'c';) 合法,char 类型可以存储单个字符。

2. 判断题:数据类型长度

问题:Java 中数据类型的长度与具体使用的机器相关。

答案错误

分析

  • Java 是一种跨平台语言,它的基本数据类型长度与平台无关,在所有平台上都保持一致。
    • 例如,int 总是占用 4 个字节(32 位),byte 总是占用 1 个字节(8 位)。

3. 表达式类型判断

问题:如果定义有 double x; float y; int m;,则表达式 x*y-m 的类型为:

A、double
B、float
C、int
D、short

答案Adouble

分析

  • xdouble 类型,yfloat 类型。根据 Java 的数据类型提升规则,floatdouble 参与运算时会提升为 double,因此表达式结果的类型为 double

4. 表达式类型判断

问题:如果定义有 short s; byte b; char c;,则表达式 s * b + c 的类型为:

A、char
B、short
C、int
D、byte

答案Cint

分析

  • 在 Java 中,byteshortchar 类型参与运算时会提升为 int 类型,因此表达式结果为 int 类型。

5. 整数溢出问题

问题:已知 int i = 2147483647; ++i;,则 i 的值等于多少?

A、-2147483648
B、2147483647
C、2147483648

答案A-2147483648

分析

  • int 类型的取值范围是 -21474836482147483647,当 i 超过其上限时,会发生溢出,结果为其最小值 -2147483648

6. byte 溢出问题

问题:已知 byte i = 127; ++i;,则 i 的值等于多少?

A、-128
B、127
C、128

答案A-128

分析

  • byte 的取值范围是 -128127,当 i 超过其上限 127 时,发生溢出,结果为 -128

7. 赋值语句编译问题

问题:已知 byte i = 127; i = i + 1;,这两行语句能否编译成功?

答案:编译不成功。

分析

  • i = i + 1; 中,i + 1 会提升为 int 类型,不能直接赋值给 byte 类型,需要进行强制类型转换,例如 i = (byte) (i + 1);

8. 自增操作问题

问题:执行以下程序段 int a = 5, b; b = ++a * 3;b 的值为:

A、17
B、18
C、16
D、15

答案B18

分析

  • ++a 先自增,a 的值变为 6,然后再进行乘法运算,b = 6 * 3 = 18

9. 按位或运算符问题

问题:如果 x = 3, y = 5,则表达式 x | y 的值为:

A、15
B、8
C、1
D、7

答案D7

分析

  • x | y 是按位或运算,二进制形式为:
    • x = 3 对应 011y = 5 对应 101,按位或的结果为 111,即 7

10. 复合赋值运算符问题

问题:如果 int a = 3, b = 2;,则执行 a *= b + 8a 的值为:

A、20
B、14
C、30
D、16

答案C30

分析

  • a *= b + 8 等价于 a = a * (b + 8),先计算 b + 8 的值为 10,然后 a = 3 * 10 = 30

11. 非法表达式判断

问题:若所用变量都已正确定义,以下选项中,非法的表达式是:

A、a != 4 || b == 1
B、'a' % 3
C、'a' = 1 / 2
D、'A' + 32

答案C

分析

  • ABD 都是合法表达式。
  • 选项 C 试图将 1 / 2 的结果赋值给字符 'a',这是非法的,因为字符类型不能进行这样的赋值操作。

19. 数组定义错误的描述

问题:设有定义语句 int a[] = {1, 1, 2};,以下对此语句的叙述错误的是:

A、定义了一个名为 a 的一维数组
B、a 数组有 3 个元素
C、a 数组的下标为 1-3
D、数组中的每个元素是整型

答案C

分析

  • A 正确:该语句定义了一个名为 a 的一维数组。
  • B 正确:数组 a 有 3 个元素,分别是 1, 1, 2。
  • C 错误:Java 中数组的下标从 0 开始,不是从 1 开始,因此 a 数组的下标应为 0-2。
  • D 正确:数组 a 的每个元素都是整型。

20. 正确的数组初始化形式

问题:以下数组初始化形式正确的是:

A、int t1[][] = {{1, 2}, {3, 4}, {5, 6}}
B、int t2[][] = {1, 2, 3, 4, 5, 6}
C、int t3[3][2] = {1, 2, 3, 4, 5, 6}
D、int t4[][]; t4 = {1, 2, 3, 4, 5, 6}

答案A

分析

  • A 正确:正确的二维数组初始化语句,定义并初始化了一个二维数组。
  • B 错误:没有使用正确的二维数组初始化语法,不能直接将一维数组赋值给 t2
  • C 错误:数组的大小应该在定义时用 [] 来声明,而不是 [] 后面紧跟数组大小。
  • D 错误:此语句没有按照正确的二维数组初始化语法来赋值。

21. 使用选择排序对数组进行降序排序

问题:编写一个程序,使用选择法对数组 a[] = {20, 10, 55, 40, 30, 70, 60, 80, 90, 100} 进行从大到小的排序。

解答

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class ArraySort {
public static void main(String[] args) {
int array[] = {20, 10, 55, 40, 30, 70, 60, 80, 90, 100};
int i, j, maxIndex, temp;

// 选择排序从大到小
for (i = 0; i < array.length - 1; i++) {
maxIndex = i;
// 寻找最大元素的下标
for (j = i + 1; j < array.length; j++) {
if (array[j] > array[maxIndex]) {
maxIndex = j;
}
}
// 交换最大元素与当前元素
temp = array[maxIndex];
array[maxIndex] = array[i];
array[i] = temp;
}

// 输出排序后的数组
System.out.println("排序后的数组:");
for (i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
}

程序解释

  1. 外层 for 循环控制排序的轮数。
  2. 内层 for 循环找到未排序部分中的最大元素的下标。
  3. 通过交换,将最大值移动到数组的当前排序位置。
  4. 最终打印排序后的数组(从大到小)。

2. 求两个整数的最大公约数

问题:编写一个程序,使用辗转相除法(欧几里得算法)求两个整数的最大公约数。

解答

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Gcd {
public static void main(String[] args) {
int a = 45;
int b = 21;
int k;

System.out.print("Gcd(" + a + "," + b + ") = ");

// 使用辗转相除法求最大公约数
while (b != 0) {
k = a % b; // 取余数
a = b; // 交换 a 和 b
b = k;
}

// 输出最大公约数
System.out.println(a);
}
}

程序解释

  1. 初始两个整数 a = 45b = 21
  2. while 循环中使用辗转相除法,不断将 a 除以 b,并更新 ab 的值,直到 b 为 0。
  3. b = 0 时,a 即为这两个数的最大公约数。
  4. 最后,输出 a 的值,即最大公约数。

打印 9*9 乘法表

问题:编写一个程序,打印 9*9 乘法表。

解答

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class MultiTable {
public static void main(String[] args) {
int i, j;
int n = 9; // 设置乘法表的最大值为9

// 打印表头
System.out.print(" | ");
for (i = 1; i <= n; i++) {
System.out.print(" " + i + " ");
}
System.out.print("\n----");
for (i = 1; i <= n; i++) {
System.out.print("----");
}
System.out.println();

// 打印乘法表内容
for (i = 1; i <= n; i++) {
// 打印左侧行号
System.out.print(i + " | ");

// 打印乘法结果
for (j = 1; j <= i; j++) {
System.out.printf("%2d ", i * j); // 格式化输出,保持整齐
}
System.out.println(); // 换行
}
}
}

程序解释

  1. 设置 n = 9,表示打印 9*9 乘法表。
  2. 首先,打印乘法表的表头,包含 1 到 9 的数字。
  3. 使用嵌套的 for 循环打印乘法表内容:
    • 外层循环控制行数 i
    • 内层循环控制列数 j,打印每一行的乘法结果。
  4. 使用 System.out.printf 格式化输出,保持数字对齐。

最终输出会是一个整齐的 9*9 乘法表,如下:

1
2
3
4
5
6
7
8
9
10
11
   |  1   2   3   4   5   6   7   8   9  
----|------------------------------------
1 | 1
2 | 2 4
3 | 3 6 9
4 | 4 8 12 16
5 | 5 10 15 20 25
6 | 6 12 18 24 30 36
7 | 7 14 21 28 35 42 49
8 | 8 16 24 32 40 48 56 64
9 | 9 18 27 36 45 54 63 72 81

已知条件

  • 公鸡 5 元 1 只
  • 母鸡 3 元 1 只
  • 小鸡 1 元 3 只
  • 用 100 元刚好买 100 只鸡

问题:问有多少种采购方案?

解答

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Loop320 {
public static void main(String[] args) {
int i, j, k;

// 打印表头
System.out.println("公鸡 母鸡 小鸡");

// 外层循环:i 为公鸡数量,最多 20 只公鸡(因为 5 * 20 = 100)
for (i = 0; i <= 20; i++) {
// 中层循环:j 为母鸡数量,最多 33 只母鸡(因为 3 * 33 = 99,接近 100 元)
for (j = 0; j <= 33; j++) {
// 根据公鸡和母鸡的数量,计算剩余的小鸡数量
k = 100 - i - j; // 小鸡数量

// 确保小鸡的数量符合条件(数量必须大于等于 0 且小鸡数量是 3 的倍数,因为1元买3只)
if (k >= 0 && k % 3 == 0) {
// 计算总花费是否等于 100 元
if (5 * i + 3 * j + k / 3 == 100) {
// 输出符合条件的公鸡、母鸡、小鸡数量
System.out.println(i + " " + j + " " + k);
}
}
}
}
}
}

程序说明

  1. 循环范围
    • i 表示公鸡的数量,最多不超过 20 只(因为每只公鸡 5 元,20 只就是 100 元)。
    • j 表示母鸡的数量,最多不超过 33 只(因为每只母鸡 3 元,33 只母鸡的花费接近 100 元)。
    • k 表示小鸡的数量,由 100 - 公鸡数量 - 母鸡数量得到。
  2. 条件判断
    • 小鸡数量 k 必须是非负数且为 3 的倍数(因为 1 元买 3 只小鸡)。
    • 计算总金额是否正好等于 100 元,即 5 * i + 3 * j + k / 3 == 100
  3. 输出:每种公鸡、母鸡、小鸡的组合都将输出符合条件的方案。

输出结果格式:

1
2
公鸡 母鸡 小鸡
...

程序运行后会输出符合条件的不同采购方案。


类与对象的关系

  • :是抽象化的概念,表示一类对象的共同属性和行为,是构造对象的模板。
  • 对象:是类的具体实例,表示现实中的实体。它包含了特定的状态,并且可以执行与这些状态相关的操作。

类和对象的关系可以概括为抽象具体的关系:

  • 是对一类对象的共性抽象,描述了该类对象的特征和行为;
  • 对象是类的具体实例,它按照类的模板生成,具有各自的特定状态。

举例说明:

  • 类与对象的关系就像零件的图纸与根据图纸制造出的零件之间的关系:
    • 图纸(类)描述了所有零件(对象)的共同特征;
    • 零件(对象)是根据图纸制造出来的,每个零件可能在一些细节上有所不同,如加工精度等,表现出个体差异。

2. 什么是方法?方法的结构是怎样的?设计方法应考虑哪些因素?

  • 方法的定义
    方法是 Java 类的一个组成部分,用来定义类的行为,通过方法可以改变对象的状态。它包含一组执行特定任务的代码块,能够接收参数并返回结果。

  • 方法的结构

    1
    2
    3
    [修饰符] 返回值类型 方法名([形参列表]) [throws 异常列表] {
    // 方法体
    }

    例如:

    1
    2
    3
    public int sum(int a, int b) throws Exception {
    return a + b;
    }
  • 设计方法时应考虑的因素

    1. 方法名
      • 方法名应该是有意义的动词或动词短语,用于描述方法的功能。
      • 遵循命名约定,方法名应采用小驼峰命名法(第一个字母小写,其他单词首字母大写)。
    2. 返回值类型
      • 可以是任意的 Java 数据类型(如 intStringboolean 等),甚至可以是定义此方法的类。
      • 如果方法不返回任何值,使用 void 关键字。
    3. 形式参数列表
      • 如果方法有参数,参数列表应该明确指定类型和参数名,用逗号分隔。
      • 如果方法没有参数,则用空括号 () 表示。
    4. throws 异常列表
      • 如果方法可能抛出异常,需在方法签名中用 throws 关键字声明可能抛出的异常类型。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Example {
// 无返回值方法
public void printMessage() {
System.out.println("Hello, World!");
}

// 带返回值和参数的方法
public int addNumbers(int a, int b) {
return a + b;
}

// 带异常抛出的方法
public void riskyOperation() throws Exception {
throw new Exception("An error occurred.");
}
}

3. 创建一个 Rectangle 类,包含两个方法,分别使用 this 关键字和不使用 this 关键字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Rectangle {
// 矩形的宽
int width;

// 使用 this 关键字的设置宽度的方法
int setWidthUsingThis(int width) {
this.width = width; // this.width 代表当前对象的 width 属性
return this.width; // 返回当前对象的宽度
}

// 不使用 this 关键字的设置宽度的方法
int setWidthWithoutThis(int width) {
int w = width; // w 是方法内的局部变量
return w; // 返回局部变量 w 的值
}

public static void main(String args[]) {
Rectangle r = new Rectangle(); // 类对象的实例化
System.out.println("It is about the node of this."); // 输出语句
System.out.println(r.setWidthUsingThis(1)); // 调用使用 this 的方法
System.out.println(r.setWidthWithoutThis(2)); // 调用不使用 this 的方法
}
}

运行结果:

1
2
3
It is about the node of this.
1
2

说明:

  • this 关键字:在 setWidthUsingThis 方法中,this.width 指代当前对象的 width 属性,以确保将参数 width 赋值给当前对象的属性。
  • 局部变量:在 setWidthWithoutThis 方法中,w 是局部变量,它的值仅在该方法的范围内有效,与类的属性 width 无关。

1. 继承

继承是面向对象程序设计中两个类之间的一种关系。当一个类(子类)获取另一个类(父类)中所有非私有的数据和操作的定义作为它自己的部分或全部时,就称这两个类之间具有继承关系。

  • 父类(超类):被继承的类。
  • 子类:继承了父类的所有非私有数据和方法的类。

继承的特性及其好处

  • 代码重用:子类可以重用父类中已有的代码,减少重复代码的编写。
  • 程序结构清晰:继承有助于建立层次结构,使得程序逻辑更加清晰。
  • 维护方便:可以通过修改父类来影响所有子类,从而降低维护成本。

单重继承与多重继承

  • 单重继承:一个类只能有一个父类。
  • 多重继承:一个类可以有多个父类(在 Java 中不支持多重继承)。

2. 子类与父类域和方法数量的关系

“子类的域和方法的数量一定大于等于父类的域和方法的数量”这种说法是错误的。原因如下:

  • 子类只能继承父类的非私有域和方法。
  • 如果子类定义的域和方法数目小于父类中私有成员的数量,则子类的域和方法的数量可能小于父类。

3. 方法的覆盖与重载

  • 方法的覆盖:子类重新定义父类中已经存在的方法,称为方法的覆盖。当子类定义的新方法与父类中的同名方法参数列表相同时,新的方法将取代父类的方法。

  • 域的隐藏:子类可以重新定义父类中的同名域,但这并不会完全取代父类的域。父类的域仍然存在并占用内存。

  • 方法的重载:在同一个类中,定义多个同名但参数列表不同的方法,这被称为方法的重载。与方法覆盖不同,重载是在同一类中进行的。

4. 多态

多态是指一个类中存在多个同名的方法,其具体实现因对象的不同而有所变化。多态体现了面向对象编程的抽象与封装的特点。

面向对象程序设计中多态的必要性及优点

  • 灵活性:通过多态,程序可以根据对象的具体类型选择合适的方法实现。
  • 简洁性与可读性:多态提高了程序的简洁性和可读性。
  • 降低耦合性:多态降低了类与程序模块之间的耦合和依赖,使得代码更易于维护和扩展。

1. 父类对象与子类对象的相互转化

条件:一个子类对象可以被视为一个父类对象,即一个父类对象的引用可以指向一个子类对象的实例。要实现父类对象与子类对象的相互转化,可以使用以下两种方式:

  • 向上转型(Upcasting):将子类对象赋值给父类引用。这是安全的,且不需要强制转换。例如:

    1
    Parent parent = new Child();
  • 向下转型(Downcasting):将父类引用转换为子类引用。这需要强制类型转换,并且在运行时必须确保父类对象实际上是一个子类对象,以避免 ClassCastException。例如:

    1
    Child child = (Child) parent;

2. 什么是包?它的作用是什么?

是一个类的集合,用于将相关的类组织在一起。其主要作用包括:

  • 组织类:将协同工作的类组织在一起,增强程序的结构性。
  • 避免命名冲突:不同的包可以有相同名称的类,避免了命名冲突。
  • 访问控制:包提供了访问控制机制,限制类和成员的访问权限。

3. CLASSPATH环境变量

CLASSPATH是一个指定Java虚拟机查找类文件(字节码文件)和包的路径的环境变量。其影响包括:

  • 编译和运行时:如果CLASSPATH设置不正确,程序在编译和运行时可能无法找到所需的类,从而导致程序无法正常运行。

设置和修改CLASSPATH

可以通过命令行设置或修改CLASSPATH,例如:

1
SET CLASSPATH=.;C:\jdk1.5.0\lib\ext

4. 类如何实现接口?是否需要重载所有抽象方法?

  • 实现接口:使用关键字 implements 来定义一个类实现某接口。例如:

    1
    2
    3
    class MyClass implements MyInterface {
    // 实现接口中的抽象方法
    }
  • 重载要求

    • 如果实现某接口的类不是抽象类,则需要实现该接口中的所有抽象方法。
    • 如果该类是抽象类,则可以选择不实现所有抽象方法。

1. 什么是异常?简述Java的异常处理机制

异常是指程序在运行过程中,由于各种不可避免的原因而产生的错误。例如,除数为零、文件找不到、网络连接失败等情况。在Java中,所有运行时可能出现的错误都被视为异常。Java提供了一个异常处理机制,用于捕获和处理这些异常,以提高程序的健壮性和可维护性。

Java的异常处理机制

Java的异常处理机制主要通过以下几个关键字实现:

  • try:用于定义可能抛出异常的代码块。该代码块中包含可能导致异常的代码。

  • catch:用于捕获在try块中抛出的异常,并提供相应的处理代码。可以有多个catch块来处理不同类型的异常。

  • finally:用于定义无论是否发生异常都将执行的代码块。通常用于释放资源(如关闭文件或网络连接)。

  • throw:用于主动抛出异常。可以抛出自定义异常或Java内置异常。

  • throws:用于声明一个方法可能抛出的异常,通常在方法签名中使用。调用该方法时,必须处理这些声明的异常。

异常的分类

Java的异常可以分为两种类型:

  • 检查异常(Checked Exception):在编译时被检查,必须被处理或声明,例如 IOExceptionSQLException

  • 运行时异常(Runtime Exception):在运行时发生,通常是由于程序逻辑错误导致的,例如 NullPointerExceptionArrayIndexOutOfBoundsException。这类异常可以选择性处理。

2. 什么是AWT,什么是Swing?

AWT(Abstract Window Toolkit)

AWT是Java提供的一套用于构建图形用户界面(GUI)的类库。它包含了一系列基本的用户界面组件,如:

  • Label:用于显示文本。
  • Button:用户可以点击的按钮。
  • TextField:单行文本输入框。
  • TextArea:多行文本输入框。
  • Checkbox:复选框。
  • List:显示一组选择项的列表。
  • Menu:下拉菜单。

AWT还提供事件处理机制,支持剪贴板操作(clipboard)和数据转换(data transfer)等功能。AWT的组件是基于本地系统的原生窗口部件,这意味着它们在不同的操作系统上表现可能略有不同。

Swing

Swing是建立在AWT之上的一个更为丰富和灵活的图形用户界面库。与AWT不同,Swing组件是完全用Java编写的,具有更好的可移植性和一致性。Swing提供了许多AWT组件的增强版本,并添加了新的组件,例如:

  • JFrame:顶级窗口,通常作为应用程序的主窗口。
  • JPanel:可容纳其他组件的容器。
  • JButton:增强的按钮。
  • JLabel:增强的标签,支持更丰富的文本格式。
  • JTable:用于显示表格数据的组件。
  • JTree:用于显示层次结构的树形组件。

Swing组件支持更丰富的用户界面定制(如主题和外观),并且所有组件都是轻量级的,不依赖于本地系统的窗口部件,这使得它们在不同操作系统上具有一致的外观和行为。

  • 异常:运行时发生的错误,Java通过异常处理机制(try、catch、finally、throw、throws)来管理。
  • AWT:Java的原生GUI工具包,提供基本组件和事件处理。
  • Swing:基于AWT的GUI工具包,提供更多功能和组件,具有更好的可移植性和一致性。

Java Applet 开发步骤

以在屏幕上显示“您好!”为例,下面简述 Java 小应用程序 Applet 的开发步骤。

1. 导入必要的包

在Java中,开发Applet需要导入一些特定的包,包括AWT(Abstract Window Toolkit)和Applet包。

1
2
3
import java.awt.*;          // 导入AWT包
import java.awt.event.*; // 导入事件处理包
import java.applet.*; // 导入Applet包

2. 创建Applet类

创建一个类,继承自Applet类,这是Applet程序的特点。使用public修饰符以确保Applet可以被访问。

1
public class Hello extends Applet {

3. 重写paint方法

重写paint方法以实现Applet的绘制。这个方法在Applet被加载或需要重新绘制时被调用。可以使用Graphics对象在Applet中绘制内容。

1
2
3
public void paint(Graphics g) {
g.drawString("您好!", 60, 60); // 在坐标(60, 60)处显示字符串“您好!”
}

4. 创建HTML文件

为了在浏览器中运行Applet,需要创建一个HTML文件来加载Applet。例如:

1
2
3
4
5
6
<html>
<body>
<applet code="Hello.class" width="300" height="200">
</applet>
</body>
</html>

5. 编译和运行

  • 将Java源文件保存为Hello.java,并在终端或命令行中编译:
1
javac Hello.java
  • 使用浏览器或Applet查看器运行HTML文件:
1
appletviewer yourfile.html

完整示例代码

1
2
3
4
5
6
7
8
9
import java.awt.*;          // 导入AWT包
import java.awt.event.*; // 导入事件处理包
import java.applet.*; // 导入Applet包

public class Hello extends Applet { // 继承Applet类
public void paint(Graphics g) { // 重写paint方法
g.drawString("您好!", 60, 60); // 显示字符串
}
}