Lab 3
Lab 3 Problem Set
题面附件代码见https://github.com/charcai/BUAA-OOP-2024/tree/main/Lab03/Lab3-Code
解答代码见https://github.com/charcai/BUAA-OOP-2024/tree/main/Lab03/
Question1: Package
浏览 Code 目录下的 Question01 目录,不允许变更目录结构和文件位置,只允许在文件中添加 package 和 import 语句,使根目录下 build 和 test 文件中的指令可以无报错顺利执行。
build和test为脚本文件,直接在 IDE 或文本编辑器中打开即可看到其中的指令。
PS.不要轻易相信IDEA自动加的,报红的是可以通过编译运行的
你可以把 Question01 目录复制到解答的压缩包中,或者在解答报告中直接以文字或截图说明你的改动。
Question2:方法重写
阅读 Code 目录下的 Question02 目录,根据你对方法重写规则的理解,回答下列问题并改正代码错误
Worker.java的1号注释处正确吗,如果不正确应该怎么改正,为什么?- 如果
Worker.java内eat()方法的修饰符改为private,可以通过编译吗,为什么? Teacher.java的2号注释处正确吗,如果不正确应该怎么改正,为什么?Teacher.java的3号注释处正确吗,如果不正确应该怎么改正,为什么?- 属性、静态方法、非静态方法,哪些可以覆盖(重写 /
override),哪些可以隐藏?
你可以把 Question02 目录复制到解答的压缩包中,或者在解答报告中直接以文字或截图说明你的改动。
Question3: super VS this
完成下面表格,复制或截图在解答报告中
| 区别点 | this | super |
|---|---|---|
| 引用(代表什么) | ||
| 使用方式 | ||
| 调用构造方法(调用谁的构造方法,放在第几条语句) | ||
| 查找范围(查找顺序) |
Question4: final
在实验报告中回答下列问题
final修饰的类可以被继承吗?可以继承其它类吗?final修饰的方法可以被重写吗?final修饰的变量相当于什么?final修饰的引用类型变量可以改变其引用地址吗?可以改变对象的内部属性的值吗?
Question5: 权限
阅读 Code 目录下的 Question05 目录,根据你对访问权限的理解。将文件中所有无法通过编译的语句注释掉。
你遇到的问题可能会集中在 protected 和默认访问权限。
从这次实验和上一次实验,可以引申出两个问题,你需要在解答中说出你的想法。
- Lab 2 中的单例模式,或者说所有构造方法都是
private时,可能有子类吗? final类可以视为所有构造方法都是private的类吗?
你可以把 Question05 目录复制到解答的压缩包中,或者在解答报告中直接以文字或截图说明你的改动。
Question6: Shape
阅读下面的二维形状类 Shape
| |
你的任务是:
- 编写
Rectangle类,a和b分别代表矩形两条边的长度(长和宽); - 编写
Rhombus类,a和b分别代表两条菱形对角线的长度; - 编写
Ellipse类,a和b分别代表椭圆两个半轴(半长轴和半短轴)的长度; - 编写一个测试类,构造子类对象并测试。
注意:
- 上述三个类都继承自
Shape类,都必须要override方法calcArea; a和b都不能是负数,当通过constructor或者setter设定为负数时,将对应的值置为0.0,或throw异常;a和b的大小关系没有任何约束,没有a必须不小于b的说法。
题外话
我们知道属性不设置为
public是为了保护数据,如果a和b在Shape中的访问权限被设置为private,在不添加新的属性的情况下,子类想要实现自己的calcArea()该怎么办?在解答中写出你的思考。
Question7: 车车
定义一个 Vehicle 类,在其中声明一个属性代表这个交通工具有多少个轮子,提供对这个属性的 setter。提供轮子类、引擎类。创建几个 Vehicle 的导出类:Motorbike、Car、Tank。自由发挥,在测试类中构造这几种交通工具,并测试功能。
其中 Motorbike 类需增加两个属性:driver 和 passenger 表示司机和乘客。增加你觉得合适的方法。
定义一个 Person 类,加入你觉得合适的属性和方法,生成 brother 和 sister 两个对象,结合 Motorbike 试图实现以下场景:
- 生成三个对象(
Motorbike实例motorbike,Person实例brother、sister) - 设置
motorbike的司机与乘客为brother和sister - 打印
motorbike的信息(尽可能详细) - 调用
sister的say()方法,输出“不像我,我只会心疼 giegie~”
备注:这道题目绝不是 2321 同学们的助教出的。
Lab 3 Assignment
Question1
代码打包为文件夹,见 ./Question01/ 目录。
Question2
修改后的文件见./Question02/。
Worker.java的1号注释处正确吗,如果不正确应该怎么改正,为什么?不正确。 可以将
@Override行删除。Worker.eat()与People.eat()所传递的参数不同,构成Overload而非Override,故签名不正确。如果
Worker.java内eat()方法的修饰符改为private,可以通过编译吗,为什么?不可以。 在
Java中,子类Override的方法不能比父类中被Override的方法有更低的访问级别。Teacher.java的
2号注释处正确吗,如果不正确应该怎么改正,为什么?不正确。 在
Java中,子类Override的方法应与父类中被Override的方法有相同的返回类型。本代码中,Teacher.work()返回类型是People,而Worker.work()返回类型是Worker。可将
Teacher.work()的返回类型改为Worker, 将返回值改为return new Worker();。Teacher.java的3号注释处正确吗,如果不正确应该怎么改正,为什么?不正确。 问题同上,在
Java中,子类Override的方法应与父类中被Override的方法有相同的返回类型。可将
Worker.salary()的返回类型改为long。属性、静态方法、非静态方法,哪些可以覆盖(重写 / override),哪些可以隐藏?
- 属性不能被覆盖,可以被隐藏。
- 静态方法不能被覆盖,可以被隐藏。
- 非静态方法可以被覆盖,不能被隐藏。
Question3
| 区别点 | this | super |
|---|---|---|
| 引用 | 当前对象的引用 | 父类对象的引用 |
| 使用方式 | 用于访问当前对象的成员变量和方法 | 用于访问当前对象的成员变量和方法 |
| 调用构造方法 | 调用当前类的其他构造方法,必须放在构造方法的第一条语句 | 调用父类的构造方法,必须放在构造方法的第一条语句 |
| 查找范围 | 从当前类开始查找 | 从父类开始查找 |
Question4
final修饰的类可以被继承吗?可以继承其它类吗?final修饰的类不能被继承,可以继承其它类。final修饰的方法可以被重写吗?final修饰的方法不可以被重写。final修饰的变量相当于什么?相当于常量。
final修饰的引用类型变量可以改变其引用地址吗?可以改变对象的内部属性的值吗?final修饰的引用类型变量不可以改变其引用地址,可以改变对象的内部属性的值。
Question5
修改后的代码见 ./Question 05/ 目录。
解答:
- Lab 2 中的单例模式,或者说所有构造方法都是 private 时,不可能有子类。
final类不完全可以视为所有构造方法都是private的类。二者都不能被继承、不能被扩展,但区别在于,final类在有public或protected的构造方法时可以被实例化,而所有构造方法都是private的类不能被外部实例化。
Question6
工程文件见 ./Question06/目录。
思考题: 如果 a 和 b 在 Shape 中的访问权限被设置为 private,在不添加新的属性的情况下,子类想要实现自己的 calcArea() 该怎么办?
可以在
Shape中实现两个方法getA()与getB(), 返回a和b的值,便可直接被外部方法调用。
Question7
工程文件见 ./Question07/ 目录。
- 交通工具的测试类为
./Question07/TestVehicles.java, - 场景的测试类为
./Question07/TestMotorbike.java。