Java面向对象实战:用继承和多态简化形状计算(附PTA练习题解)
最近在辅导一些初学Java的同学时,我发现很多人在面对PTA(程序设计类实验辅助教学平台)上那些关于“形状计算”的题目时,往往会陷入一种“功能实现”的思维定式。他们能写出计算矩形面积、圆形周长的代码,但当题目要求同时处理多种形状,并输出总面积和总周长时,代码就变得冗长、重复,充满了if-else的判断。这其实是一个绝佳的契机,让我们跳出面向过程的泥潭,真正体会继承和多态这两大面向对象核心思想所带来的优雅与力量。本文将从一道经典的PTA习题出发,手把手带你重构代码,让你不仅知道语法怎么写,更能理解为什么要这么设计,以及这种设计在实际项目中能带来怎样的巨大优势。
1. 从“过程式”泥潭到“面向对象”的优雅转身
很多初学者在初次接触这道题时,可能会写出类似下面的代码结构:
Scanner in = new Scanner(System.in);
int n = in.nextInt();
double totalArea = 0;
double totalPerimeter = 0;
ArrayList<String> infoList = new ArrayList<>();
for (int i = 0; i < n; i++) {
String type = in.next();
if (type.equals("rect")) {
int width = in.nextInt();
int length = in.nextInt();
// 计算矩形
double area = width * length;
double perimeter = 2 * (width + length);
totalArea += area;
totalPerimeter += perimeter;
infoList.add("Rectangle [width=" + width + ", length=" + length + "]");
} else if (type.equals("cir")) {
int radius = in.nextInt();
// 计算圆形
double area = 3.14 * radius * radius;
double perimeter = 2 * 3.14 * radius;
totalArea += area;
totalPerimeter += perimeter;
infoList.add("Circle [radius=" + radius + "]");
}
}
// 输出结果
System.out.println(totalPerimeter);
System.out.println(totalArea);
System.out.println(infoList);
这段代码能跑通,但问题非常明显:计算逻辑分散在多个if-else分支中,且与数据输入、结果收集的代码高度耦合。想象一下,如果题目要求新增一个三角形,你需要:
- 增加一个
else if分支。 - 在里面重新编写三角形的面积和周长计算公式。
- 修改结果收集的逻辑。
- 整个过程极易引入错误,且代码会像面条一样越拉越长。
注意:这种“根据类型判断,然后执行对应操作”的模式,是典型的过程式思维。面向对象编程的目标之一,就是消除这种显式的类型判断,让代码自己“知道”该做什么。
继承和多态为我们提供了解决方案。其核心思想是:将“是什么”与“做什么”绑定在一起。矩形和圆形都是“形状”,它们都有计算面积和周长的行为,但具体如何计算,是各自特有的。我们可以先定义一个抽象的“形状”契约,然后让具体的形状去实现这个契约。这样,处理形状数组的代码就完全不需要关心当前是矩形还是圆形,它只需要统一地“命令”每个形状去计算自己的面积和周长即可。
2. 构建抽象层:定义Shape契约
我们的重构之旅从顶层设计开始。我们需要一个能代表所有形状共性的抽象概念。在Java中,我们使用

&spm=1001.2101.3001.5002&articleId=149585510&d=1&t=3&u=ca9e3531508c40a990d2a286f5ca2357)
9090

被折叠的 条评论
为什么被折叠?



