OOpre笔记(2)
Lec3:继承与接口
继承的定义
- 继承:让子类获得父类的属性和方法,实现代码复用和拓展,减少冗余度并增强课维护性。
- 使用语法:
- 子类中,使用
extends关键字继承父类。
1
2
3class 子类 extends 父类 {
// 子类定义
}- 子类可以访问父类的公共(public)和受保护(protected)成员
- 私有(private)成员无法被直接被访问,需调用父类的方法来访问
- Java只支持单继承,一个类最多只能有一个父类
- 子类中,使用
super.attribute可以引用父类中定义的非私有属性 - 子类中,使用
super.methodName()关键字调用父类中定义的非私有方法。
1
2
3
4
5class 子类 extends 父类 {
public void method() {
super.methodName();
}
}- 子类中,可以重写父类中的方法。方法名称、参数列表和返回类型必须保持一致.
1
2
3
4
5
6class 子类 extends 父类 {
public void method() { // 重写父类中的方法
// 子类方法实现
}
} - 子类中,使用
重写(Override)
- @Override 注解:可选的注解,用于标记重写方法,提高代码可读性
- 访问权限:重写方法的visibility范围必须大于等于父类方法
- 如果父类方法为public,子类方法只能为public
- 返回类型:重写方法必须与父类方法的返回类型一致
- 若父类方法返回类型为基本类型,则只能相同
- 若父类方法返回类型为AClass,则只能返回AClass或者其子类的对象
- 方法名和参数列表:重写方法必须与父类方法完全相同
- 参数个数和参数顺序、参数类型
继承带来的便利:
- 减少冗余:子类不必重复实现父类已有的属性和方法,直接获得
- 如,在编写新的药水瓶类
XBottle的时候,只需要使用XBottle extends Bottle来声明 - 只需编写
XBottle独有的属性或方法 - 根据
Xbottle的具体要求重写Bottle中的方法
- 如,在编写新的药水瓶类
- 层次结构:上层类可以概括下层类
- 可以用
Bottle来引用Xbottle_obj,Adventurer类不需要新增容器来储存Xbottle实例 - 任何以
Bottle对象为参数的方法,都可以传入Xbottle对象进行统一处理
- 可以用
继承的使用情景
- 提炼场景:多个类之间存在相同的属性和方法
- 将相同(公共)的部分提取出来形成一个类(父类)
- 避免出现重复代码
- 更好的维护这些相同的属性和代码
- 扩展场景:引入新类,避免对已有类进行修改
- 新类对已有类进行增量式扩展
- 避免编写冗余代码
- 保持已有类及其使用者的稳定
继承的优势
- 代码重用
- 子类无需重复实现父类的属性和方法,提高了重用度
- 代码拓展
- 子类可以添加新的属性和方法,实现自己独有的功能
- 实现了对父类的增量式扩展(保持父类不变,因而其使用者也不变
- 继承层次
- 形成抽象层次结构,任何子类对象都可以使用父类型来统一引用和管理
- 实现了对各种变化的统一处理能力
接口
- 接口是一种定义方法和常量的抽象类型,不提供方法实现。
- 一个接口可以被多个类实现,一个类也可以实现多个接口。
- 通过实现接口来定义程序所需的行为,消除类之间的依赖关系。
- 使用语法:
接口中,使用public关键字定义方法。类中,使用1
2
3interface 接口名 {
public void method();
}implements关键字实现接口。
继承与接口的选择
- 当存在明显父子关系时选择继承。
- 当需要定义不同类间的共同行为时选择接口。
继承下的Junit测试注意事项
- 测试子类时注意是否调用了父类方法和访问了父类属性。
- 测试其他类的方法时,注意参数的类型是子类型还是父类型。
Lec4: JAVA程序的BUG分析与调试
多种输入指令的处理策略
-
使用
switch case语句
每种指令封装为一个方法,通过switch判断执行:1
2
3
4
5switch (operator) {
case 1: command1(...); break;
case 10: command10(...); break;
//...
} -
面临的问题
随着指令增多,main函数中顺序处理变得复杂。可以通过设计一个父类CommandUtil来简化:- 设计父类:如
CommandUtil,提供command(String message)方法。 - 子类继承:具体的指令子类如
AddBottle、AddEquipment。 - 管理命令:
Manager类负责管理多个CommandUtil对象,并根据输入动态调用合适的命令。
- 设计父类:如
-
管理命令对象
Manager类通过ArrayList<CommandUtil>存储所有命令,并通过输入指令自动获取并执行对应命令:1
2cmdUtil = cmdUtilArray.get(operator - 1);
cmdUtil.command(message);
常见逻辑性错误
-
引用错误
-
空指针异常:当试图通过
null对象访问其成员时会抛出空指针异常:1
2String str = null;
int len = str.length(); // 抛出NullPointerException
-
索引越界异常:访问数组或容器中元素时,索引超出范围会产生索引越界异常:
1
name = list.get(index); // 当index超出范围时抛出IndexOutOfBoundsException

- 类型转换错误:数据类型不匹配时会引发类型转换错误:
1
2Shape shape = new Circle();
Rectangle rect = (Rectangle) shape; // 抛出ClassCastException
-
-
运算错误
- 逻辑运算短路求值:在Java中,逻辑运算符
||和&&存在短路行为,可能影响程序执行:
1
2
3
4String test = null;
if (test == null || test.length() > 5) {
// 正确:不会触发空指针异常
}1
2
3
4String test = null;
if (test.length() > 5 || test == null){
// 错误:会触发空指针异常
}- 隐式强转与类型提升:数值赋值时可能发生隐式强制转换,导致溢出或精度丢失:
1
2byte b = 10;
b += 1020; // 隐式类型提升
- 逻辑运算短路求值:在Java中,逻辑运算符
-
控制流错误
差一错误:指循环次数或索引值与预期相差1,常见于数组遍历:1
2for (int i = 0; i <= array.length; i++) { // 错误:索引越界
}
差一错误的防范
-
只需对下述三种状态进行检测:
- 0状态:迭代还未发生时,检查程序状态是否符合预期
- 1状态:进行了一次迭代,检查迭代结果以及迭代后的程序状态是否符合预期
- m状态:多次迭代,观察迭代得到的结果并判断能否在预期次数时终止
-
对于遍历数组 string,需进行如下测试:
- 0状态:检查(string != null && string.length > 0)
- 1状态:进行一次迭代,观察是否得到了第0个元素
- m状态:迭代10次,观察第10次迭代是否正常得到最后一个元素,再进行一次迭代,观察有无引发空指针异常,观察迭代是否已经终止
-
类似地,采用这三个步骤也可解决“差 k 错误”
-
输入输出错误
- Scanner的nextLine问题:使用
nextLine吸收换行符时,未及时处理会导致错误:
1
2
3
4
5
6
7
8
9
10
11
12
13public class NextLineExample {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入你的年龄:");
int age = sc.nextInt();
System.out.println("请输入你的姓名:");
String name = sc.next();
System.out.println("请输入你的工资:");
String salary = sc.nextLine();// 这里会吸收前一个输入的换行符,导致salary为空
System.out.println("你的信息如下:");
System.out.println("姓名:"+name+"\n"+"年龄:"+age+"\n"+"工资:"+salary);
}
}- next类方法
- next, nextInt, nextDouble, nextFloat
- 扫描System.in直到获得了有效输入,并把有效输入之前的其他符号过滤掉(如空格和回车等)
- 无法获得带有空格的输入
- nextLine方法
- 获得回车之前的整行输入(吸收回车)
- Bug原因:输入姓名后按下的回车不会被next吸收,nextLine 在吸收后直接返回
- 解决办法
- next后添加一个 nextLine 方法
- 或者都使用next类方法
- Scanner的nextLine问题:使用
-
拷贝错误
- Java中的对象传参是传递引用(即地址值),而非复制对象内容,导致对象被意外共享:
- 产生对象共享访问
- 一个对象可能被其他对象修改,导致状态变化
- 如果这种对象状态变化是不受控制的,则需要限制对象共享
- 使用一个对象的拷贝来进行传递处理
- Object类内置有clone 方法
- 浅拷贝:对于对象中的引用类型属性,复制其引用值(地址值)
- 单层拷贝
- 默认的clone方法是浅拷贝
- 深拷贝:对于对象中的引用类型属性,复制其内容(层次迭代)
1
2
3
4
5Address addr = new Address("CityA");
Factory fact1 = new Factory("Factory1", addr);
Factory clonedFact = (Factory) fact1.clone();
clonedFact.getAddress().setCity("CityB");
// 修改了clonedFact的属性,fact1的属性也发生变化 - Java中的对象传参是传递引用(即地址值),而非复制对象内容,导致对象被意外共享:
-
String类使用不当
- String是普遍使用的一个类
- String s1 = “OOpre"; // 直接创建
- String s2 = “OOpre"; // 直接创建
- String s3 = s1; // 引用赋值
- String s4 = new String(“OOpre"); // String 对象创建
- String s5 = new String(“OOpre"); // String 对象创建
- 这五个对象引用是否存在共享?

- equals与==的区别:
equals比较内容,==比较引用地址。String类是不可变对象,修改时返回新对象。
- String是普遍使用的一个类
错误捕捉与处理
-
错误传播
- 程序运行时的错误可能会通过方法调用链传播,导致问题复杂化。因此需要通过
try-catch来捕捉异常:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21class ExceptionExample {
void m() {
int data = 50 / 0;
}
void n() {
m();
}
void p() {
n();
}
}
public class Test {
public static void main(String args[]) {
ExceptionExample obj = new ExceptionExample();
try {
obj.p();
} catch (Exception e) {
e.printStackTrace();
}
}
} - 程序运行时的错误可能会通过方法调用链传播,导致问题复杂化。因此需要通过
-
错误扩散与捕捉
- 如果对象的属性取值错误,访问该对象的所有方法都会受到影响。通过
try-catch捕捉错误,防止扩散。
- 如果对象的属性取值错误,访问该对象的所有方法都会受到影响。通过
黑盒测试
-
测试的重点
- 构造数据覆盖不同场景,验证程序的输入输出是否符合预期。黑盒测试关注程序的外部表现,不关注内部实现。
-
等价类划分
- 根据程序对输入的处理逻辑,将输入划分为若干等价类,每个等价类中的数据会触发相同的处理逻辑:
- 有效等价类 vs 无效等价类
- 通过划分等价类来减少测试工作量,提高测试效率。
- 根据程序对输入的处理逻辑,将输入划分为若干等价类,每个等价类中的数据会触发相同的处理逻辑:
调试方法
-
数据化简
- 问题的输入数据往往很大或复杂,需要化简数据,确保在最小数据集上仍能重现问题,以便于调试。
-
断点调试
- 行断点:程序执行到某行时暂停。
- 条件断点:满足特定条件时暂停。
- 断点反映调试人员的推理过程,动态调整断点位置可以帮助更好地发现问题。
-
打印语句调试
- 通过插入打印语句来监控程序执行过程中的变量状态和逻辑分支,辅助发现问题。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 theUHO!
评论







![2025 年数据库大作业 [BUAA-DB]](http://gitee.com/TheUHO/blog/raw/master/images/202407212255287.jpg)
![2026年算法设计与分析期末回忆版[BUAA-算法]](https://gitee.com/TheUHO/blog/raw/master/images/202407212255294.jpg)
![VLA模型技术代码调研学习 [VLA]](https://gitee.com/TheUHO/blog/raw/master/images/202409111007683.jpg)