前言:
Java语言程序设计的学习将告一段落,现在在此对最后这段时间的练习在知识点,题量,难度等情况进行个人总结:
(1)家居强电电路模拟程序3
题目: 模拟复杂电路,涉及串联和并联电路的模拟,需要处理电阻、电压分布和设备状态的综合管理。线路中包含多个串联起来的并联电路。
题量:新增器件互斥开关,线路中包含多个串联起来的并联电路。
难度:只新增了互斥开关这一器件,难度中等。
(2)家居强电电路模拟程序4
题目:模拟复杂电路,涉及串联和并联电路的模拟,并联电路之间可能出现包含关系。
题量:增加管脚电压的显示,增加电流限制,增加短路检测,并联电路中包含并联,新增器件二极管。
难度:对于输入输出有着巨大的改变,新增了短路检测以及电流限制也是难题。本次迭代难度大。
知识点总结:
(1)java类中对于继承和多态的使用。
(2)关于电路的设计,对于每个电器的电压处理
(3)Java中对于Map和List的使用
(4)对于异常的处理:trycatch块:捕获并处理可能出现的运行时异常,如短路检测。
(5)使用Comparator对设备列表进行排序。
设计与分析
(1)家居强电电路模拟程序3
类图:
抽象基类 Device
属性:
id:设备的标识符。
inputVoltage:设备的输入电压。
resistance:设备的电阻值。
hasVoltage:表示设备是否带有电压。
方法:
构造函数:初始化设备ID。
getStatus:抽象方法,用于获取设备的状态。
getId:返回设备的ID。
connectPin:连接设备的引脚(默认实现为空)。
toggle:切换设备状态(默认实现为空)。
stepUp:增加设备的一个状态级别(默认实现为空)。
stepDown:减少设备的一个状态级别(默认实现为空)。
set:设置设备的输入电压。
getInputVoltage:获取设备的输入电压。
getResistance:获取设备的电阻值。
getTotalResistance:获取设备的总电阻值(默认实现返回电阻值)。
电路结构类
SeriesCircuit 类(串联电路):
属性:devices 存储串联的设备列表。
方法: addDevice 添加设备到串联电路,getStatus 获取电路状态,set 设置电路电压,getTotalResistance 计算总电阻,checkForOpenCircuit 检查电路是否开路。
ParallelCircuit 类(并联电路):
属性:devices 存储并联的设备列表,equivalentResistance 等效电阻值。
方法: addDevice 添加设备到并联电路,getStatus 获取电路状态,set 设置电路电压,calculateEquivalentResistance 计算等效电阻,getTotalResistance 获取等效电阻值。
具体设备子类
Switch 类(开关):
属性:isClosed 表示开关是否关闭,connectedDevice 连接的设备。
方法: getResistance 返回电阻值(开关关闭时为0),getStatus 获取开关状态,toggle 切换开关状态,set 设置开关电压并传递给连接的设备。
Dimmer 类(分档调速器):
属性:level 表示分档调速器的级别,connectedDevice 连接的设备。
方法: getResistance 返回电阻值(调光器为0),getStatus 获取调光器状态,stepUp 和 stepDown 调整级别,set 设置调光器电压并更新连接的设备。
Lamp 类(日光灯):
属性:level 表示日光灯的亮度级别,connectedDevice 连接的设备。
方法: getResistance 返回电阻值(灯泡为0),getStatus 获取灯泡状态,setLevel 设置亮度级别,set 设置灯泡电压并更新连接的设备。
Bulb 类(白炽灯):
属性:brightness 表示白炽灯的亮度。
方法: getResistance 返回电阻值,getStatus 获取灯泡状态,set 根据输入电压设置灯泡亮度。
** SelectorSwitch 类(选择开关)**
属性:
isConnectedToPin2:标识是否连接到引脚2。
connectedDevice2:连接到引脚2的设备。
connectedDevice3:连接到引脚3的设备。
方法:
getResistance:返回电阻值。
getStatus:获取开关状态。
toggle:切换开关状态。
connectPin:连接设备到引脚。
set:设置开关电压。
Resistor 类(连续调速器):
属性:isOn 表示连续调速器是否开启。
方法: getResistance 返回电阻值,getStatus 获取连续调速器状态,set 根据输入电压设置连续调速器状态。
MotorD 类和 MotorA 类(电扇):
属性:speed 表示电扇的速度。
方法:getResistance 返回电扇值,getStatus 获取电扇状态,set 根据输入电压设置电扇速度。
Main 类
属性:
voltage:静态变量,表示电源电压。
方法:
main:程序入口,读取输入并处理设备状态。
createDevice:根据设备ID创建具体的设备实例。
parseConnectionInfo:解析连接信息,创建并连接设备。
applyControlInfo:应用控制信息,如开关操作。
printDeviceStatus:打印所有设备的状态。
(2)家居强电电路模拟程序4
类图:
以下是对您提供的代码的分析:
** 抽象基类 Device**
属性:
id:设备的标识符。
inputVoltage:设备的输入电压。
resistance:设备的电阻值。
hasVoltage:表示设备是否带有电压。
totalResistance:设备的总电阻值。
deviceVoltage:设备上的电压。
maxCurrent:最大电流限制。
pinVoltages:跟踪每个管脚的电压。
方法:
构造函数:初始化设备ID。
getStatus:抽象方法,用于获取设备的状态。
getId:返回设备的ID。
connectPin:连接设备的引脚(默认实现为空)。
toggle:切换设备状态(默认实现为空)。
stepUp:增加设备的一个状态级别(默认实现为空)。
stepDown:减少设备的一个状态级别(默认实现为空)。
set:设置设备的输入电压。
getInputVoltage:获取设备的输入电压。
getResistance:获取设备的电阻值。
getTotalResistance:获取设备的总电阻值(默认实现返回电阻值)。
setPinVoltage:设置特定管脚的电压。
getPinVoltage:获取特定管脚的电压。
电路结构类
** SeriesCircuit 类(串联电路)**
属性:
devices:存储串联的设备列表。
isMainCircuit:标识是否为主电路。
isOpenCircuit:标识电路是否开路。
isInParallelCircuit:标识电路是否在并联电路中。
方法:
addDevice:添加设备到串联电路。
getStatus:获取电路状态。
set:设置电路电压。
getTotalResistance:计算总电阻。
checkForOpenCircuit:检查电路是否开路。
ParallelCircuit 类(并联电路)
属性:
devices:存储并联的设备列表。
equivalentResistance:等效电阻值。
方法:
addDevice:添加设备到并联电路。
getStatus:获取电路状态。
set:设置电路电压。
calculateEquivalentResistance:计算等效电阻。
getTotalResistance:获取等效电阻值。
具体设备子类
** Switch 类(开关)**
属性:
isClosed:表示开关是否关闭。
方法:
getResistance:返回电阻值(开关关闭时为0)。
getStatus:获取开关状态。
toggle:切换开关状态。
set:设置开关电压。
** Dimmer 类(分档调速器)**
属性:
level:表示分档调速器的级别。
方法:
getResistance:返回电阻值(调光器为0)。
getStatus:获取调光器状态。
stepUp:增加调光器级别。
stepDown:减少调光器级别。
set:设置调光器电压。
ContinuousDimmer 类(连续调光器)
属性:
level:表示连续调光器的级别。
方法:
getResistance:返回电阻值(调光器为0)。
getStatus:获取调光器状态。
setLevel:设置调光器级别。
set:设置调光器电压。
** IncandescentBulb 类(白炽灯)**
属性:
brightness:表示白炽灯的亮度。
方法:
getResistance:返回电阻值。
getStatus:获取灯泡状态。
set:根据输入电压设置灯泡亮度。
** FluorescentLamp 类(日光灯)**
属性:
brightness:表示日光灯的亮度。
方法:
getResistance:返回电阻值。
getStatus:获取灯泡状态。
set:根据输入电压设置灯泡亮度。
** CeilingFan 类(吊扇)**
属性:
speed:表示吊扇的速度。
方法:
getResistance:返回电阻值。
getStatus:获取电扇状态。
set:根据输入电压设置电扇速度。
PedestalFan 类(台扇)
属性:
speed:表示台扇的速度。
方法:
getResistance:返回电阻值。
getStatus:获取电扇状态。
set:根据输入电压设置电扇速度。
** Curtain 类(窗帘)**
属性:
openPercentage:表示窗帘的开启百分比。
方法:
getResistance:返回电阻值。
getStatus:获取窗帘状态。
adjustCurtain:根据光照强度调整窗帘。
** Diode 类(二极管)**
属性:
conducting:表示二极管是否导通。
方法:
getResistance:返回电阻值(导通时为0,截止时为无穷大)。
getStatus:获取二极管状态。
set:设置二极管电压。
** SelectorSwitch 类(选择开关)**
属性:
isConnectedToPin2:标识是否连接到引脚2。
connectedDevice2:连接到引脚2的设备。
connectedDevice3:连接到引脚3的设备。
方法:
getResistance:返回电阻值。
getStatus:获取开关状态。
toggle:切换开关状态。
connectPin:连接设备到引脚。
set:设置开关电压。
** Main 类**
属性:
voltage:静态变量,表示电源电压。
R:静态变量,表示总电阻。
shortCircuitDetected:静态变量,标识是否检测到短路。
方法:
main:程序入口,读取输入并处理设备状态。
createDevice:根据设备ID创建具体的设备实例。
parseConnectionInfo:解析连接信息,创建并连接设备。
applyControlInfo:应用控制信息,如开关操作。
printDeviceStatus:打印所有设备的状态。
代码的逻辑:
代码的流程逻辑可以分为几个主要部分:解析连接信息、应用控制信息、计算电路状态和打印设备状态。以下是详细的流程分析:
1. 解析连接信息 (parseConnectionInfo)
从输入中读取以T和M开头的连接信息行。
对于T行,表示串联电路,创建SeriesCircuit对象,并根据行中的内容添加设备到串联电路中。
对于M行,表示并联电路,创建ParallelCircuit对象,并根据行中的内容添加串联电路或其它并联电路到当前并联电路中。
所有设备和电路都被存储在devices映射中,以设备ID为键。
2. 应用控制信息 (applyControlInfo)
从输入中读取以开头的控制信息行。
根据控制信息行的格式,对相应的设备执行操作,如开关切换(toggle)、分档调速器级别调整(stepUp/stepDown)、连续调光器级别设置(setLevel)等。
3. 计算电路状态
对于每个SeriesCircuit,如果它不是开路并且不在并联电路中,计算其总电阻并将其添加到总电阻R中。
对于每个ParallelCircuit,计算其等效电阻并将其添加到总电阻R中。
如果是连续调光器,根据其标志和级别设置主电路电压。
对于每个SeriesCircuit,如果它不是开路并且不在并联电路中,设置电路电压。
对于每个ParallelCircuit,计算其等效电阻,并检查是否发生短路。如果没有短路,根据等效电阻和主电路电压设置并联电路中每个设备的电压。
4. 打印设备状态 (printDeviceStatus)
将所有设备按类型和ID排序。计算总光照强度,用于调整窗帘的开合。根据光照强度调整窗帘的状态。打印每个设备的状态。
5. 主程序流程 (main)
读取输入直到遇到"end"。解析连接信息,创建设备和电路结构。应用控制信息,改变设备状态。打印所有设备的状态。如果检测到短路,输出短路错误信息。
采坑心得
1. 对于单串联电路上对于互斥开关的处理
一开是只是简单粗暴地判断互斥开关是否存在连接来判断电路的连通,无论连通的是1-2还是1-3接口,导致并联时会将存在互斥开关的两条电路都是为通路。
错误代码
public boolean checkForOpenCircuit() {
/* if (isInParallelCircuit) {
return false; // 如果串联电路在并联电路中,不检查断路
}*/
for (Device device : devices) {
if (device instanceof Switch) {
if (!((Switch) device).isClosed) {
return true;
}
} else if (device instanceof SelectorSwitch) {
SelectorSwitch selectorSwitch = (SelectorSwitch) device;
if (!selectorSwitch.isConnectedToPin2() && !selectorSwitch.isConnectedToPin3()) {
return true;
}
}
}
return false;
}
解决方法:
我现在串联电路类中新增属性,跟踪互斥开关连接到2号端口的数量。
Public int exclusiveSwitchPin2Count = 0;
再修改判断条件就可以正确判断了
if ((exclusiveSwitchPin2Count1&&selectorSwitch.isConnectedToPin2())||(exclusiveSwitchPin2Count0&&selectorSwitch.isConnectedToPin3())) {
return true;
}
2. 对输出器件顺序的方法
sortedDevices.sort(Comparator.comparing(
(Device device) -> {
int typeOrder;
if (device instanceof Switch) typeOrder = 1;
else if (device instanceof Dimmer) typeOrder = 2;
else if (device instanceof ContinuousDimmer) typeOrder = 3;
else if (device instanceof IncandescentBulb) typeOrder = 4;
else if (device instanceof FluorescentLamp) typeOrder = 5;
else if (device instanceof CeilingFan) typeOrder = 6;
else if (device instanceof PedestalFan) typeOrder = 7;
else if (device instanceof SelectorSwitch) typeOrder = 8;
else if (device instanceof Curtain) typeOrder = 9;
else typeOrder = Integer.MAX_VALUE;
return typeOrder;
}
).thenComparing(Comparator.comparing(Device::getId)));
3.当电路上的器件的引脚的电位出现差错,比如当左边引脚的电压小于右边电压,即并联中还有并联电路时,里面的并联电路会出现电压差导致电路“错向”的情况,产生另一种的回路。但是很可惜,没有写出来。
改进建议
-
方法分解:一些方法(如printDeviceStatus)非常长,包含了多个逻辑步骤。可以将这些方法分解成更小的、功能单一的方法,以提高代码的可读性和可维护性。
-
避免重复代码:在多个地方看到类似的代码块,例如在printDeviceStatus方法中对串联和并联电路的处理。可以将这些重复的代码块抽象成单独的方法。
-
异常管理:代码中使用了RuntimeException来处理短路情况。可以考虑定义一个专门的异常类来处理电路中可能出现的各种异常情况,这样可以提供更丰富的错误信息,并允许调用者以不同的方式处理这些异常。
-
输入验证:在处理用户输入(如控制信息)时,代码应该验证输入的有效性,并在输入无效时提供清晰的错误消息。
-
空值检查:在访问可能为null的对象成员之前,应该进行空值检查,以避免NullPointerException。
总结:
通过本次家居强电电路模拟程序,我学习了面向对象编程的实际应用,掌握了如何使用类和对象来模拟现实世界的电路系统。我也理解了电路中的基本物理概念,比如电压、电流和电阻,并学会了如何在代码中实现这些概念。在代码管理方面,我认识到了代码组织的重要性,包括如何命名变量和方法、编写注释和文档,这些都是提高代码可读性和可维护性的关键。同时,我也了解了基本的错误处理和异常管理,这对于编写健壮的软件来说至关重要。
本学期,我通过PTA平台学习Java,我不仅掌握了Java的基础知识和编程技巧,还通过解决实际问题提升了我的问题解决能力和逻辑思维。这个过程充满了挑战,但每次解决一个难题,我都能感受到巨大的成就感和乐趣(爽)。但是在编程时总是碰到一些难以攻破的难题,比如家居强电电路模拟程序中关于并联的相关部分没有写好,导致后面的题目没有获得好的分数。
总的来说,本学期对于java的学习是充满乐趣与挑战的,确切地提升了我的问题解决能力和逻辑思维。
标签:Blog3,getStatus,电路,电阻值,并联,电压,设备 From: https://www.cnblogs.com/jianglingzzz/p/18638171