Lab 3: 类与对象

本次 Lab 时长为 2 周,DDL 为 10 月 2 日 23:59。😁

附件下载(包括问答题和实验报告模板):https://bhpan.buaa.edu.cn/link/AA96D0CA694BB74ABFA070F38B6C527AC6

实验目的

  • 理解并掌握类的概念
  • 理解并掌握对象的概念
  • 理解类与对象的关系
  • 理解面向对象中抽象过程
  • 理解面向对象中的消息
  • 理解 Java 程序的基本结构并能灵活使用
  • 理解并掌握 Java 类的定义(成员变量、成员方法和方法重载)
  • 理解并掌握 Java 类的构造函数(默认构造函数、带参数构造函数),理解重
    载的构造函数并灵活使用
  • 理解 Java 垃圾内存自动回收机制
  • 理解并掌握 Java 类变量和类方法

本次代码量相对较多,请大家注意文件结构的规划。🫡


1. 类的定义

Question 1

编译 Sample 类,并查看编译结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Sample {
int x; // 1
long y = x; // 2

public void f(int n) {
int m; // 3
int t = n + m; // 4
}

public static void main(String[] args) {
Sample t = new Sample();
t.f(5);
System.out.println(t.x);
}
}

注释标记的哪些行会导致编译错误?将错误截图,并说明原因。


2. 函数重载

Question 2

阅读下面代码

1
2
3
4
5
6
7
8
9
10
11
public class Overload {
Overload(int m) {}

Overload(double m) {}

int Overload(int m) {
return 23;
}

void Overload(double m) {}
}

对于 Overload 类,下面哪些叙述是错误的?给出你的回答,并说明原因。

  • a. Overload(int m)Overload(double m) 互为重载的构造方法。
  • b. int Overload(int m)void Overload(double m) 互为重载的非构造方法。
  • c. Overload 类有 2 个构造方法,尝试调用默认构造方法 Overload() 会无法通过编译。
  • d. Overload 类有 3 个构造方法。

Question 3

阅读下面这段代码。

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
30
31
public class Overload2 {
int a, b;
int c = -1;

public Overload2() {
a = -2;
}

public Overload2(int p1, int p2) {
a = p1;
b = p2;
}

public Overload2(int p1, int p2, int p3) {
this(p1, p2);
c = p3;
}

@Override
public String toString() {
return String.format("(a,b,c)=(%d,%d,%d)", a, b, c);
}

public static void main(String[] args) {
Overload2 s = new Overload2();
System.out.println(s);
System.out.println(new Overload2(5, 6));
System.out.println((new Overload2(2, 3, 4)).toString());
}
}

运行 main 函数,将程序的输出截图

题外话

根据 void java.io.PrintStream.print() 系列函数的实现,当传入的 StringObjectnull 时,最后都会导致输出字符串 null,而不是什么都不输出。

进行字符串连接时也一样:" " + null 的结果是 null

因此当涉及相关操作时需要稍微注意一下。

具体原因参见 java.io.PrintStreamjava.lang.String 的源代码。


3. 编程题

Question 4

写一个音乐类,并编写测试类显示音乐信息(音乐名称、音乐类型)。

写一个手机类,并编写测试类显示手机信息(手机品牌、手机型号)。

除了提交 .java 代码外,你需要在解答中说明如下内容:

1
2
目录名为:Question4(或者你自己的命名)
文件名有:(如果你放了一个项目进来,则说明你的项目结构以及入口位置)

唠叨两句:手机类和音乐类都需要完成“显示信息”这样的功能,那我们能否将这一功能封装起来实现呢?

比如我们可以让手机类和音乐类都实现一个 IMessage 接口, 他们就有了统一的测试方法。

1
2
3
4
5
6
7
8
class Test {
public static void main(String[] args) {
IMessage music = new Music();
IMessage mobile = new Mobile();
music.print();
mobile.print();
}
}

当然,在这个题中,使用这样的实现方式未免有点“过度封装”。如果之后完成个人/团队大作业时遇到了类似的场景,不妨在想一想能否应用上述的模式进行设计。

Question 5

编写程序,在其中定义两个类

  • Person 类:
    • 属性有 nameagesex
    • 提供你认为必要的构造方法;
    • 方法 setAge() 设置人的合法年龄(0~130);
    • 方法 getAge() 返回人的年龄;
    • 方法 work() 输出字符串 working
    • 方法 showAge() 输出 age 值。
  • TestPerson 类:
    • 创建 Person 类的对象,设置该对象的 nameagesex 属性;
    • 调用 setAge()getAge() 方法,体会 Java 的封装性;
    • 创建第二个对象,执行上述操作,体会同一个类的不同对象之间的关系。

除了提交 .java 代码外,你需要在解答中说明如下内容

1
2
目录名为:Question5(或者你自己的命名)
文件名有:(如果你放了一个项目进来,则说明你的项目结构以及入口位置)

Question 6

编写一个 Java 命令行程序,只从标准输入读取一行用户输入,判断这行输入是否是一个没有前导 0 的无符号整数;如果是,则还要判断该数字是否是一个回文数。自定义你程序的输出,要求能直观展现程序判断的结果。

对于“没有前导 0 的无符号整数”的定义:

  • 是一个字符串 s
  • s 的长度至少是 1,没有上限要求;
  • s 的字符集 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},其他所有字符都不应该出现在 s 中;
  • s 的长度大于 1 时,若从其首部开始有若干个连续字符 0,那么这些字符 0 都叫做 s 的“前导 0”。
    • 比如数字串 00010020,有三个前导 0
    • 比如数字串 01,有 1 个前导 0
    • 比如数字串 102030,没有前导 0
    • 比如数字串 0,没有前导 0

本题对于回文数的定义:

  • 是一个字符串 s
  • s 的长度至少是 1,没有上限要求
  • s 的字符集 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},其他所有字符都不应该出现在 s
  • s 中的字符逆序排列并去除前导 0 得到的数字串 r ,有 sr 完全相同
    • s = 123 时,r = 321,不相同,s 和 r 都不是回文数
    • s = 12321 时,r = 12321,相同,s 是回文数
    • s = 12100 时,r = 121,不相同,s 不是回文数,但 r 是回文数
    • s = 1 时,r = 1,相同,s 是回文数
    • s = 0 时,r = 0,相同,s 是回文数

本题将输入的一行字符视为一个完整的字符串,如果输入的是诸如“121 121”这样包含空格的串,虽然 121 是回文数,但是整个串不应该被认为是回文数。如果将字符集扩充为包含空格的其他字符集,那么“121 121”就是一个该字符集下的回文串,不过本题的字符集限定为由 0 ~ 9 这十个数字组成的字符集。

除了提交 .java 代码外,你需要在解答中说明如下内容:

1
2
目录名为:Question6 (或者你自己的命名)
文件名有:(如果你放了一个项目进来,则说明你的项目结构以及入口位置)