OOP-面向对象的程序设计7~8
家居强电电路模拟程序3
这次程序设计要求相较于前一次增加了
互斥开关:
互斥开关有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。
吊扇,落地扇
吊扇:
工作电压区间为80V-150V,对应转速区间为80-360转/分钟。80V对应转速为80转/分钟,150V对应转速为360转/分钟,超过150V转速为360转/分钟(本次迭代暂不考虑电压超标的异常情况)。其他电压值与转速成正比,输入输出电位差小于80V时转速为0。
落地扇:
工作电压区间为 80V-150V,对应转速区间为 80-360 转/分钟;[80V,100V) 对应转速为 80 转/分钟;[100,120)V 对应转速为 160 转/分钟;[120,140)V 对应转速为 260 转/分钟;大于等于 140V 转速 为 360 转/分钟。
受控窗帘:
受控窗帘:当电路中所有灯光的光照强度总和在[0,50)lux范围内,窗帘全开;
在[50,100)lux范围内,窗帘打开比例为0.8;
在[100,200)lux范围内,窗帘打开比例为0.6;
在[200,300)lux范围内,窗帘打开比例为0.4;
在[300,400)lux范围内,窗帘打开比例为0.2;
在400lux及以上范围内,窗帘关闭。
当电压低于50V,窗帘不工作,默认为全开状态。
如果电路中没有灯或者灯全部关闭,光照强度为0,窗帘处于全开状态。
类的设计如下:
点击查看代码
//窗帘
class S extends App {
int stage;
double brightness;
public S(String name, int stage, double brightness) {
super(name);
this.stage = stage;
this.brightness = brightness;
super.setResistance(15);
}
public int getStage() {
return stage;
}
public void setStage(int stage) {
this.stage = stage;
}
public double getBrightness() {
return brightness;
}
public void setBrightness(double brightness) {
this.brightness = brightness;
}
@Override
public void change(double brightness) {
if (brightness >= 0 && brightness < 50) {
this.stage = 100;
} else if (brightness >= 50 && brightness < 100) {
this.stage = 80;
} else if (brightness >= 100 && brightness < 200) {
this.stage = 60;
} else if (brightness >= 200 && brightness < 300) {
this.stage = 40;
} else if (brightness >= 300 && brightness < 400) {
this.stage = 20;
} else {
this.stage = 0;
}
}
public void show() {
System.out.println("@" + super.getName() + ":" + this.stage + "%");
}
所有电路元件考虑电阻:
受控设备电阻:白炽灯的电阻为 10,日光灯的电阻为 5,吊扇的电阻为 20,落地扇的电阻为 20,窗帘电阻为15。
串联电路
整体设计上在上次设计的基础上添加
串联电路库:
用于记录每一条除了主电路以外串联电路的所有信息以及状态,以供并主电路中的串联电路和并联电路选择使用。
代码如下:
点击查看代码
//一条串联电路
class Line {
private String name;
private double voltage;
private ArrayList<App> list = new ArrayList<>();
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
private boolean stage;
public void setStage(boolean stage) {
this.stage = stage;
}
public boolean getStage() {
return stage;
}
public boolean isStage() {
for (int i = 0; i < list.size(); i++) {
if (list.get(i) instanceof H) {
H h = (H) list.get(i);
boolean b = text.contains(h.getName() + "-2");
if (h.isStage() && !b) {
return false;
} else if (b && !h.isStage()) {
return false;
}
}
}
for (int i = 0; i < list.size(); i++) {
if (list.get(i) instanceof K) {
K k = (K) list.get(i);
if (k.getStage() == false) {
stage = false;
return false;
}
}
}
stage = true;
return true;
}
public double getAllresistance() {
double allresistance = 0;
for (int i = 0; i < list.size(); i++) {
if (list.get(i) instanceof H) {
H h = (H) list.get(i);
if (h.isStage()) {
list.get(i).setResistance(5);
} else {
list.get(i).setResistance(10);
}
}
allresistance += list.get(i).getResistance() * 1.00000;
}
return allresistance;
}
public ArrayList<App> getList() {
return list;
}
public void setList(ArrayList<App> list) {
this.list = list;
}
public Line(String name, double voltage, ArrayList<App> list) {
this.name = name;
this.voltage = voltage;
this.list = list;
}
public double getVoltage() {
return voltage;
}
public void setVoltage(double voltage) {
this.voltage = voltage;
}
public Line() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Line(String name) {
this.name = name;
}
}
并联电路类
其中成员包含并联电路名称,组成并联电路的串联电路子路名称,同时包含多个方法(计算并返回串联电路的总电阻,返回整条电路的连通状态,判断电路是否短路)
代码如下:
点击查看代码
//并联电路
class ParallelConnection {
private String name;
private String[] linename;
public double getPararesistance(ArrayList<Line> alllist) {
int px = 0;
double[] x = new double[linename.length];
for (int i = 0; i < x.length; i++) {
for (int j = 0; j < alllist.size(); j++) {
if (alllist.get(j).getName().equals(linename[i])) {
if (alllist.get(j).isStage() && alllist.get(j).getAllresistance() == 0 && alllist.get(j).getStage()) {
px = 1;
} else if (alllist.get(j).isStage() && alllist.get(j).getAllresistance() != 0 && alllist.get(j).getStage()) {
x[i] = alllist.get(j).getAllresistance();
} else {
x[i] = 0;
}
}
}
}
double sum = 0;
for (int i = 0; i < x.length; i++) {
if (x[i] != 0) {
sum += 1 / x[i];
}
}
if (px == 1) {
return 0;
}
return 1 / sum;
}
//并联电路是否通路
public boolean ifaccess(ArrayList<Line> alllist) {
int flag = 0;
for (int i = 0; i < linename.length; i++) {
for (int j = 0; j < alllist.size(); j++) {
if (alllist.get(j).getName().equals(linename[i])) {
if (alllist.get(j).isStage() == true && alllist.get(j).getStage()) {
flag = 1;
}
}
}
}
if (flag == 0) {
return false;
}
return true;
}
public ParallelConnection(String name, String[] linename) {
this.name = name;
this.linename = linename;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getLinename() {
return linename;
}
public void setLinename(String[] linename) {
this.linename = linename;
}
}
主电路类
成员包含:1.主电路组成部分名称,2.该部分状态判断(单个元件/串联电路/并联电路),3.电路元件对象(当该组成部分不是单个元件时,为null),4.该部分所分配的电压
整体思路简述:
创建串联电路list,创建主电路list,并联电路list,创建Brightness用于记录亮度;
使用while循环读入整个电路的信息,在读入控制元件的调控并修改以储存的控制元件的数据;
通过对主电路上开关的是否闭合,串联电路并联电路是否连通,判断整条电路是否连通,如果不连通则初始化电压为0;
如果连通则对电压进行初始化判单主电路第一个元件是否为调速器如果是则按照相应的挡位进行电压初始化;
计算主电路各个部分的电阻,并根据初始化电压分配到各个主电路组成部分电压;
按照非陪电压遍历主电路的list,并将处理后的数据添加到输出类(ForShow参见上一blog最后部分)中;
如果是单个元件直接根据分配的电压处理添加即可;
如果为串联电路,则按照该部分所分配电压再按照该部分的个元件电阻分配一次电压,处理各个元件并添加到输出类中;
如果为并联电路则判断是否有特殊情况并进行特殊处理,处理后分配电压并处理各个元件并将处理后的元件逐个添加到输出类中;
同时记得如果为照明元件,则按照光照强度对Brightness进行修改;
最后按照输出类的方法将各个元件有序的输出,此处注意受控窗帘需特殊处理首先判断其所分配的电压是否有50V,如果有则按照整个光照强度处理其状态并输出。
注意事项:1.主电路不连通的情况
2.并联电路电压计算(有支路短路,有支路短路,整个并联电路不连通等等情况)
3.受控窗帘的特殊处理
4.输出顺序按照字符集排序使用compareTo比较
类图如下:
家居强电电路模拟程序4
这次电路模拟设计添加了较多考察点:并联电路中包含并联电路,串联电路中包含并联串联电路,串联电路中包含串联电路,同时添加了元件二极管,电路出现短路时直接输出短路信息,正常情况需要输出各个元件的输入与输出电压,同时输入与输出电压可能反接,同时互斥开关需要输出三个脚引的电压。
1)增加管脚电压的显示
在输出每个电器的状态信息后,再依次输出该电器每个管脚的电压。(格式详见输出信息部分)
2)电流限制
电器在工作时,过大的电流会引起电器过热,从而烧坏电路。本次迭代,每个元器件都有最大电流的设置,当实时电流超过最大电流时,在该电器输出信息的最后加入提示“exceeding current limit error”,与前面的信息之间用英文空格分隔。
例如:@B1:190 68-17 exceeding current limit error
本题各类电器的最大限定电流如下:
开关20、分档调速器18、连续调速器18、白炽灯9、日光灯5、吊扇12、落地扇14、互斥开关20、受控窗帘12、二极管8。
3)短路检测
如果电路出现无穷大的电流造成短路,所有元器件信息不输出,仅输出提示“short circuit error”
4)并联电路中包含并联
本次迭代考虑并联电路中包含并联电路的情况,即构成并联电路的串联电路可以包含别的并联电路。例如如下输入的电路,并联电路M2的其中一条串联电路T4中包含了另一条并联电路M1:
.#T1:[IN D2-1] [D2-2 H1-2] [H1-1 OUT]
.#T2:[IN D1-1] [D1-2 H1-3] [H1-1 OUT]
.#M1:[T1 T2]
.#T4:[IN K3-1] [K3-2 M1-IN] [M1-OUT OUT]
.#T5:[IN K1-1] [K1-2 B1-1] [B1-2 OUT]
.#M2:[T4 T5]
5)二极管
增加二极管元件,其电路特性为:正向导通,反向截止;其电器符号如图4所示,当电流从左至右流过时,二极管导通”conduction”,电阻为0;电流从右至左流动时,二极管截止”cutoff”,电阻无穷大,相当于开关打开。
图2 二极管符号
二极管的标识符为’P’,左侧管脚编号为1,右侧管脚编号为2。
二极管如果两端电压相等,没有电流流过,分以下两种情况输出:
1、如果两端电压为0,二极管的导通/截止状态由接入方向决定,1号引脚靠近电源则状态为导通,反之为截止。
2、如果两端电压不为0,二极管导通。
这题包含一种递归的思路应用,即并联电路与串联电路可以相互包含并循环往复:
这里我选择使用方法之间的相互调用解决这个问题:
创建两个方法处理串联电路数据,处理并联电路数据,均包含输入输出电压,同时将处理后的数据添加到输出类中;
将所有要输出的信息复合到一起,最终进行排序输出。
处理电路的方法如下:
点击查看代码
//单段串联电路的处理
public static ArrayList<Line> lineprocessing(double start, Line line, double volotage,
ArrayList<Line> alline, double generator) {
if (Double.isNaN(generator)) {
generator = 0;
}
if (Double.isNaN(volotage)) {
generator = 0;
}
ArrayList<Object> list = line.getList();
double res[] = new double[list.size()];
double total = 0;
//计算电阻分配电压
for (int i = 0; i < list.size(); i++) {
if (list.get(i) instanceof App) {
res[i] = ((App) list.get(i)).getResistance();
total += res[i];
} else if (list.get(i) instanceof ParallelConnection) {
res[i] = ((ParallelConnection) list.get(i)).getPararesistance(alline);
total += res[i];
} else if(list.get(i) instanceof Line){
res[i] = ((Line) list.get(i)).getVoltage();
total += res[i];
}
}
for (int i = 0; i < list.size(); i++) {
double vo = volotage * res[i] / total;
if (list.get(i) instanceof App) {
App app = (App) list.get(i);
if (i == 1) {
if (list.get(i - 1) instanceof H) {
H h = (H) list.get(i - 1);
h.setOthers((int) start);
list.set(i - 1, h);
}
}
//&&
System.out.println(app.getName() + "电压:" + vo + "电流" + generator);
if (app instanceof H) {
H h = (H) app;
if (i > 0) {
App x = (App) list.get(i - 1);
h.setOthers((int) x.getInputVoltage());
}
h.setInputVoltage(start);
start = start - vo;
h.setOutputVoltage(start);
if (generator == 0) {
if(vo!=0){
app.setOutputVoltage(app.getInputVoltage());
}
else{
app.setOutputVoltage(0);
start = 0;
}
}
list.set(i, h);
} else if (app instanceof K) {
app = change(app, vo);
K k = (K) app;
app.setInputVoltage(start);
start = start - vo;
app.setOutputVoltage(start);
if (generator == 0 && k.getStage() == false) {
app.setOutputVoltage(0);
start = 0;
} else {
app.setOutputVoltage(start);
}
app.setGenerator(generator);
list.set(i, app);
} else {
app = change(app, vo);
app.setInputVoltage(start);
start = start - vo;
app.setOutputVoltage(start);
app.setGenerator(generator);
list.set(i, app);
}
} else if (list.get(i) instanceof Line) {
alline = lineprocessing(start, (Line) list.get(i), vo, alline, generator);
} else {
ParallelConnection p = (ParallelConnection) list.get(i);
alline = parprocessing(start, vo, p, alline, generator);
}
}
//更新线路库的数据
for (int i = 0; i < alline.size(); i++) {
if (alline.get(i).getName().equals(line.getName())) {
alline.set(i, line);
}
}
return alline;
}
//并联电路路段处理
public static ArrayList<Line> parprocessing(double start, double volotage,
ParallelConnection par, ArrayList<Line> alline, double generator) {
String[] names = par.getLinename();
double[] generators = new double[names.length];
double[] res = new double[names.length];
double sum = 0;
int tex = 0;
if (par.access(alline)) {
tex = 1;
}
int flag = -1;
//计算并联分录的电阻
for (int i = 0; i < names.length; i++) {
for (int j = 0; j < alline.size(); j++) {
if (alline.get(j).getName().equals(names[i])) {
res[i] = alline.get(j).getAllresistance(alline);
if (res[i] == 0) {
flag = i;
break;
}
if (!Double.isInfinite(res[i])) {
sum += res[i];
}
}
}
}
//给各个分路分配电流
if (flag != -1) {
generators[flag] = generator;
} else {
for (int i = 0; i < names.length; i++) {
if (Double.isInfinite(res[i])) {
generators[i] = 0;
} else {
if (sum - res[i] == 0) {
generators[i] = generator;
} else {
generators[i] = generator * (sum - res[i]) / sum;
}
}
}
}
ParallelConnection parallelConnection = par;
for (int i = 0; i < names.length; i++) {
for (int j = 0; j < alline.size(); j++) {
if (alline.get(j).getName().equals(names[i])) {
Line line = alline.get(j);
if (line.isStage(alline)) {
alline = lineprocessing(start, line, volotage, alline, generators[i]);
} else {
alline = lineprocessing(start, line, 0, alline, generators[i]);
}
}
}
}
return alline;
}
添加输出的方法思路简单就不赘述了,
类图如下:
由于特殊情况考虑不周到,还是缺失了很多点,尽管本次得分并不尽人意,但总体而言此次收获颇丰。
收获:
1.管理类的成员变量和方法:学习如何定义类的属性和方法,以及如何通过对象访问和操作这些成员。
理解继承和多态
2.使用继承扩展功能:通过继承已有的类来创建新的类,实现代码的重用和扩展性。
实现多态性:理解多态的概念,学会如何使用多态来编写灵活和可维护的代码。
熟悉封装原则
3.数据隐藏和封装:学习如何将数据和方法封装在类中,以保护数据的完整性和安全性。
使用访问修饰符:理解并使用访问修饰符(如private、protected、public)来控制成员的访问级别。
理解接口和抽象类
4.异常处理机制:学习如何使用try-catch-finally结构来处理程序中的异常情况。
自定义异常:理解如何自定义异常类,并在程序中抛出和处理自定义异常。
5.面向对象分析:学会如何从现实世界问题中抽象出对象模型,进行面向对象的分析。
面向对象设计:掌握面向对象的设计原则,如单一职责原则、开闭原则等,并应用到实际设计中。
增强自学和解决问题的能力
6.自主学习资源:通过查阅文档、教程和社区讨论,提高自学新技术的能力。
7.解决编程问题:在编程实践中遇到问题时,能够独立寻找解决方案,提高问题解决能力。