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
。