前言:
对于我这种水平的学生来说本次的7-8次PTA的难度之大令我无从下手,况且之前的第6次PTA就已经让我望而止步了,更别提这两次在第6次PTA题目集之上再次进行迭代的题目了。再加上面临的期末周,大量学科等着我去复习,以至于没时间去钻磨PTA的改动,哭死,连老师都说单单是第8次题目集的题目他就看了不少于一个小时的时间,这也侧面反映出了题目难度之大,堪称题目集难度之最。不过我还是非常羡慕那些对于这两次PTA题目集能够及格的同学的,先不说他们设计的如何,至少他们得到了分。
下面请允许我总结一下本学期关于面向对象程序与设计的总结:
-
**一、 OOP,即面向对象编程,是一种主流的计算机编程范式,它通过将数据和操作这些数据的方法组织成对象来设计软件。这种编程方式模仿了人们在现实世界中对事物的认知方式,从而使得代码结构更加清晰,易于理解、维护和扩展。OOP的核心机制主要包括以下几点:
-
(1)封装:封装是将对象的状态(数据成员,通常称为属性)和行为(成员函数,通常称为方法)捆绑在一起,并对外界隐藏其内部实现细节的过程。通过这种方式,对象的使用者只需要知道如何通过对象提供的公共接口(如方法)与其交互,而无需了解其内部工作原理,这有助于减少模块间的耦合,增强程序的安全性和可维护性。
-
(2) 继承:继承允许一个类(子类或派生类)继承另一个类(父类或基类)的属性和方法。这不仅促进了代码的重用,还支持了类与类之间的层次结构构建,使得子类能够在其父类的基础上增加新的功能或修改已有功能,从而实现软件的可扩展性。
-
(3) 多态:多态指的是允许使用一个接口来表示多种类型的实体。具体来说,子类可以覆盖或实现父类的方法,尽管调用代码可能不知道对象的确切类型,但仍然能够通过相同的接口调用相应的方法,得到针对不同对象类型的特定行为。多态提高了代码的灵活性和可复用性。
此外,面向对象编程还强调抽象,即通过定义抽象类或接口来描述对象的共同特征,而不需要关注具体实现细节。这有助于设计者专注于系统的主要组成部分以及它们之间的关系,而不必立即陷入实现细节中。
二、 -
1.关于知识点的总结:
通过这一学期所学的所有关于java的知识点,我们了解到了java的类与类之间的关系:继承、实现、依赖、关联、聚合、组合;学习到了掌握类与对象的基本概念;类的声明、创建与使用方法、类的构造方法的定义与使用方法、成员方法的定义与使用方法、类方法与实例变量、引用变量与对象实例之间的关系与区别;方法调用时引用类型参数的传递过程、掌握private、protected、public等关键的使用场合与使用方法、对象组合的方式与方法、Java中方法重载的实现方式。Java语言中抽象类的基本概念及使用方法、Java语言中接口的基本概念及使用方法、理解程序设计中常用数据结构的用法、Java语言中List相关类的使用方法、Java中Collections.sort方法的使用。
最后的最后,老师对我们提出了一个翻转课堂的任务,同学们自己上来讲关于JavaFX的知识点,下面的同学和老师则进行相应的打分;上去的同学有的可以看出来是经过精心准备的,不管是其对大家展示的PPT还是演绎代码抑或是上面的讲解员,大家对其小组都非常认可,当然也存在某些偷工减料的小组,其上前展示的内容可以说是不忍直视,连老师都对其发表了批判言论,指责该小组的无作为和不重视。 -
2.题目集的题量:
题量较之前的题目集而言并未添加多少,甚至于每次的题目集都只包含了一道题目不过每个题目集都包含了大量的设计与套路在其中。 -
3.题目集的难度
第七次的题目集可以来说是比较中等的难度,如果说第六次题目集设计合理的话,完全可以在第六次的基础上进行迭代,但第八次题目集则达到了难度之最:从同学们的提交情况来说,这是第一次没有同学100分的情况,大部分同学都是50分以下当然还有一大堆的零分;连老师都表示这题都看了至少一个小时。综上而言,第八次PTA的难度很大,需求很多。
设计与分析:
-
第七次大作业
-
新增内容:
互斥开关有3个引脚:1个是汇总引脚,另两个是分支引脚。
开关电路示意图如图1所示,左边是汇总引脚,编号为1;右边两个是分支引脚,右上的输出引脚为2,右下输出引脚为3。图中1、2、3引脚均可以是输入引脚,当1为输入引脚时,2、3引脚为输出引脚;1为输出引脚时,2、3引脚为输入引脚。
互斥开关只有两种状态:开关接往上面的2号引脚、接往下面的3号引脚。开关每次只能接通其中一个分支引脚,而另一个分支引脚处于断开状态。
互斥开关的默认状态为1、2引脚接通,1、3引脚断开。
为避免短路,互斥开关设置了限流电阻,12引脚之间默认电阻为5,13引脚之间默认电阻为10。// 假设存在一个基本的Switch类,它至少有 isOpen 状态和 toggle() 方法 public abstract class Switch { protected boolean isOpen; public Switch() { this.isOpen = false; // 初始状态为关闭 } public boolean isOpen() { return isOpen; } public abstract void toggle(); // 抽象方法,由子类实现开关的切换逻辑 }
// 互斥开关类实现
public class MutuallyExclusiveSwitch extends Switch {
private static MutuallyExclusiveSwitch[] switches; // 静态数组存储所有互斥开关实例
private static int count = 0; // 记录当前已创建的互斥开关数量
public MutuallyExclusiveSwitch() {
super();
if (switches == null) {
switches = new MutuallyExclusiveSwitch[10]; // 假设最多支持10个互斥开关
}
switches[count++] = this;
}
@Override
public void toggle() {
if (!isOpen) { // 只有当开关关闭时尝试打开
for (MutuallyExclusiveSwitch sw : switches) {
if (sw != null && sw.isOpen()) {
sw.isOpen = false; // 关闭所有其他已打开的开关
}
}
this.isOpen = true; // 然后打开当前开关
} else {
this.isOpen = false; // 如果已经是打开状态,则关闭
}
}
// 其他可能需要的方法,比如获取状态、设置互斥组等
}
在这个设计中,MutuallyExclusiveSwitch类通过维护一个静态数组来跟踪所有创建的互斥开关实例。当调用toggle()方法试图打开一个开关时,它会首先关闭所有其他已经打开的互斥开关,然后再打开当前开关。这样就确保了任何时候只有一台互斥开关是开启的。
-
存在的问题:
-
1.资源泄漏:静态数组switches会持续持有所有创建过的互斥开关实例的引用,即使某些开关已经不再使用,这可能导致内存泄漏。可以通过弱引用或在不再需要时显式地从数组中移除引用的方式来改善。
-
2.默认构造和初始化问题:类的构造函数没有对count进行校验,如果创建的实例超过了数组的预设长度,可能会导致数组越界错误。应该在构造函数中加入逻辑来处理这种情况。
-
3.可扩展性和灵活性:互斥开关的逻辑直接硬编码在类中,这限制了其可扩展性和灵活性。例如,如果未来需要不同的互斥策略(比如允许多个开关同时打开,但不超过一定数量),当前设计难以适应。可以通过引入策略模式或更灵活的配置选项来提高扩展性。
-
设计类图
-
第八次大作业
-
新增内容:
本题新增内容:
1)增加管脚电压的显示
在输出每个电器的状态信息后,再依次输出该电器每个管脚的电压。(格式详见输出信息部分)
2)电流限制
电器在工作时,过大的电流会引起电器过热,从而烧坏电路。本次迭代,每个元器件都有最大电流的设置,当实时电流超过最大电流时,在该电器输出信息的最后加入提示“exceeding current limit error”,与前面的信息之间用英文空格分隔。
本题各类电器的最大限定电流如下:
开关20、分档调速器18、连续调速器18、白炽灯9、日光灯5、吊扇12、落地扇14、互斥开关20、受控窗帘12、二极管8。
3)短路检测
如果电路出现无穷大的电流造成短路,所有元器件信息不输出,仅输出提示“short circuit error”
4)并联电路中包含并联
本次迭代考虑并联电路中包含并联电路的情况,即构成并联电路的串联电路可以包含别的并联电路。例如如下输入的电路,并联电路M2的其中一条串联电路T4中包含了另一条并联电路M1:
5)二极管
增加二极管元件,其电路特性为:正向导通,反向截止;其电器符号如图4所示,当电流从左至右流过时,二极管导通”conduction”,电阻为0;电流从右至左流动时,二极管截止”cutoff”,电阻无穷大,相当于开关打开。
二极管的标识符为’P’,左侧管脚编号为1,右侧管脚编号为2。
二极管如果两端电压相等,没有电流流过,分以下两种情况输出:1、如果两端电压为0,二极管的导通/截止状态由接入方向决定,1号引脚靠近电源则状态为导通,反之为截止。
2、如果两端电压不为0,二极管导通。
对ElectricalComponent类的扩展:
public abstract class ElectricalComponent {
protected String name;
protected List<Pin> pins;
protected double maxCurrent; // 新增:最大电流限制
public ElectricalComponent(String name, List<Pin> pins, double maxCurrent) {
this.name = name;
this.pins = pins;
this.maxCurrent = maxCurrent;
}
// ... 其他原有方法 ...
// 新增方法:计算并返回当前电流
public abstract double calculateCurrent();
// 新增方法:输出状态信息及管脚电压
public String statusWithVoltage() {
StringBuilder sb = new StringBuilder();
sb.append("@").append(name).append(": ");
// 假设状态或参数值通过某种方式计算或获取
// sb.append("状态或参数值 ").append(" ");
for (Pin pin : pins) {
sb.append(pin.getPinNumber()).append("-").append(Math.round(pin.getVoltage())).append(" ");
}
// 检查电流是否超过限制
double current = calculateCurrent();
if (current > maxCurrent) {
sb.append("exceeding current limit error");
}
return sb.toString().trim();
}
}
对LoadDevice类的更新:
public abstract class LoadDevice extends ElectricalComponent {
public LoadDevice(String name, List<Pin> pins, double maxCurrent) {
super(name, pins, maxCurrent);
}
// 假设具体的电流计算逻辑依赖于设备的特性
@Override
public double calculateCurrent() {
// 根据设备的工作状态和电压差计算电流,这里仅为示例
double voltageDifference = pins.get(0).getVoltage() - pins.get(1).getVoltage();
return voltageDifference / someResistance; // someResistance根据具体设备确定
}
// 使用基类的statusWithVoltage()方法,无需重写,因为电流限制检查已在基类完成
}
- 存在的问题:
- 1.互斥开关的特殊性未处理:原始问题中特别提到了互斥开关,但示例代码中没有具体实现互斥开关的电流计算和状态更新逻辑,特别是在考虑电流限制时,互斥开关的状态改变可能影响到整个电路的电流分布。
- 2.短路检测与处理缺失:虽然提到了电流限制,但没有具体实现短路检测逻辑。在实际电路中,短路会导致电流异常增大,可能需要在电路模拟的框架中加入短路检测机制,以确保电路模拟的合理性和安全性。
- 3.电阻和功率计算的缺失:在真实电路中,每个设备都有一定的电阻,这影响着电流和电压的分配。此外,功率(电压乘以电流)的计算也是评估设备工作状况的重要因素,但在提供的示例中并未涉及。
踩坑心得与改进建议:
- 应考虑新增的互斥开关在电路之中的位置情况,视不同情况而考虑不同过程或结果
- 写代码的时候总是会产生注释偏少的问题,由于觉得写注释会消耗大量时间,所有很多时候都懒得写这些注释,但日后如果还是这样子的代码,完全不利于他人理解,这样就不利于团队之间的沟通和联系,在这方面确实值得改进。
- 在代码设计的过程中应及时考虑到我们在课堂之上学到的各种设计原则和设计模式,比如:工厂模式、抽象工厂模式、建造者模式......各种模式应均考虑进来。
总结:
- 1.在我们的学习方面应熟悉更多方法,如String里面的contains方法、Map类里面的clear()方法、Set类里面的contains()方法,以及使用StringBuffer里面的如append()、insert()、delete()、replace()等方法,使得字符串的构建、修改和操作变得非常灵活方便。
- 2.对于正则表达式的知识还是值得我们加以练习,因为很多时候单就正则表达式就会卡我们很长一段时间,这也就导致明明感觉上是可以写出来的但实际操作的时候就因为这里的难处而卡住了整个作业的进程,真的很让人头疼。
- 3.对于各种设计模式大家还是应该去认真学习一下,设计模式是在软件工程中经常使用的、经过验证的解决方案,用于处理在设计应用程序或系统时反复出现的问题,选择合适的设计模式可以提升代码的可维护性、可扩展性和复用性。
本学期本门课程的改进建议及意见
- 1.个人觉得老师有必要对于PTA作业进行一个讲解,就算没讲解也应该发一个参考代码出来,因为如果单单只是发一个类图出来很多同学看了还是一个稀里糊涂的状态,对PTA的改进没起到任何作用。而对于这些失利的同学而言也就会导致其信心的大幅下降,而且之前遇到的问题在后续的题目集中依旧是会存在的,这也就进一步导致后面的PTA难以下手。
- 2.虽然老师总是说将以后在公司遇到的问题前移,但我们在学校还只是初步学习的阶段,老师大可以在我们掌握了大部分基础知识之后再拿出“问题前移”这一操作,在拥有一定基础后遇到的问题总比零基础或低基础阶段遇到问题时无论是信心还是毅力都会明显增强。