oop 4~6總結
前言
- 知識點
繼承:第四次作業中新增的ChoiceQuestion
和GapFillingQuestion
繼承Question
類;第五次作業中Switch
, SteppedSpeedController
, ContinuousSpeedController
, IncandescentLamp
, FluorescentLamp
, 和 CeilingFan
都繼承Device
類,從而共享其屬性和方法。
集合框架:使用List
, Map
等集合來儲存和管理物件。以第五次作業為例,Map: CircuitSimulator
類使用 LinkedHashMap
儲存裝置資訊,它保持插入順序,並且提供對映功能;Iterator: 在 applyVoltage
方法中,使用迭代器遍歷 devices
集合,處理每個裝置的電壓的輸入和輸出。
正規表示式:第四次大作業中我按照老師給出的設計建議新寫了InputMatching類用來處理輸入,在InputMatching.matchInput
方法中使用正規表示式來匹配和解析使用者輸入。
抽象類: 第五次大作業中Device
是一個抽象類,它定義了所有裝置共有的屬性和方法。updateState
和 getOutput
是抽象方法,需要在子類中實現。
點選檢視程式碼
abstract class Device {
protected double inputVoltage; // 輸入電位
protected double outputVoltage; // 輸出電位
protected int number;//編號
protected int type;//裝置型別
public Device() {
}
public Device(int number) {
this.number = number;
}
public void setInputVoltage(double inputVoltage) {
this.inputVoltage = inputVoltage;
}
public double getOutputVoltage() {
return outputVoltage;
}
public void setOutputVoltage(double outputVoltage) {
this.outputVoltage = outputVoltage;
}
public int getType() {
return type;
}
public abstract void updateState(); // 更新裝置狀態
public abstract void getOutput(); // 獲取裝置輸出
}
多型: 第五次作業在 CircuitSimulator
類的 applyControlCommand
方法中,根據裝置型別呼叫不同的方法,如 sw.setState(!sw.getState())
、sc.up()
和 sc.down()
等。
型別轉換與型別檢查:在 CircuitSimulator
的 applyControlCommand
和 Main
類的主迴圈中,使用了大量的型別轉換和型別檢查(如 (Switch) device
和 device instanceof Switch
)。
-
題量
整體的題量不算多,但是很難,每道題目的側重點都稍有不同。若能認真完成作業上的題目,將每道題都理解透徹,就會對個人能力的提升有特別大的幫助。
-
難度
個人認為答題判題程式寫到第四題的時候是完全不會寫的,特別特別的難。老師們為了學生考慮又將大作業改成了電路題目,比之前的那道簡單一點點但我還是覺得很難。這就是自己的問題了,程式設計能力沒有得到提升,今後的學習還需要態度端正認真對待。更改題目是我沒有想到的,老師們是最好的老師!
設計與分析
第四次作業 答題判題程式-4
原始碼分析
設計思路
這道題目我是在上道題的基礎上又結合了老師給出來的設計建議做了修改,新增加了部分的類。
-
Question類中的
Judge
方法用於判斷學生答案的正確性,對於基礎題目,它只進行簡單的字串比較。
public String Judge(String studentAnswer) {
if (answer.equals(studentAnswer)) {
return "true";
} else {
return "false";
}
}
-
ChoiceQuestion類繼承
Question
類,代表一個選擇題,有可能包含多個正確答案。其中的getAnswers方法返回一個正確答案列表,這裡用Arrays.asList方法將答案字串按空格分割,但這樣只能處理單個答案的情況,對於多選題可能不合適。怎麼處理多選題的答案我沒有做出來。Judge方法針對選擇題的特點進行了修改,增加了對部分正確的判斷。
public List<String> getAnswers() {
return Arrays.asList(this.getAnswer().split(" "));
}
public String Judge(String studentAnswer) {
if (this.getAnswers().contains(studentAnswer)&& !this.getAnswers().equals(studentAnswer)) {
return "partially correct";
}
else if (this.getAnswers().equals(studentAnswer)) {
return "true";
}
else
return "false";
}
-
GapFillingQuestion
類繼承Question類,代表一個填空題。 -
DataWarehouse
類作為資料倉儲,用於儲存題目、試卷、學生和答卷的資訊。它提供了新增和管理這些內容的方法。
class DataWarehouse {
private Map<Integer, Question> questions;
private Map<Integer, TestPaper> testPapers;
private Map<String, Student> students;
private Map<String, AnswerPaper> answerPapers;
public DataWarehouse() {
this.questions = new HashMap<>();
this.testPapers = new HashMap<>();
this.students = new HashMap<>();
this.answerPapers = new HashMap<>();
}
public Map<Integer, TestPaper> getTestPapers() {
return testPapers;
}
public Map<String, AnswerPaper> getAnswerPapers() {
return answerPapers;
}
// 新增題目
public void addQuestion(Question question) {
questions.put(question.getNumber(), question);
}
// 新增試卷
public void addTestPaper(TestPaper testPaper) {
testPapers.put(testPaper.getNumber(), testPaper);
}
// 新增學生
public void addStudent(Student student) {
students.put(student.getId(), student);
}
// 新增答題卷
public void addAnswerPaper(AnswerPaper answerPaper) {
answerPapers.put(answerPaper.getID(), answerPaper);
}
// 根據編號獲取題目
public Question getQuestion(int number) {
return questions.get(number);
}
// 根據編號獲取試卷
public TestPaper getTestPaper(int number) {
return testPapers.get(number);
}
// 根據學生編號獲取學生
public Student getStudent(String studentId) {
return students.get(studentId);
}
}
InputMatching
類負責解析使用者輸入的指令,並根據指令更新DataWarehouse
中的資料。這個類使用正規表示式來匹配不同型別的輸入,並呼叫相應的方法進行處理。
心得體會
由於第三次的題目我就寫的比較吃力,經過迭代後的第四次更復雜更難了,首先在心理上我就是懼怕的,再加上程式設計能力不夠,因此不足以應對這種環環相扣的比較複雜的題目,最終寫出來的僅僅是半成品,只能對多選題進行輸入輸出,遇到填空題就會報錯。
一週的時間按理來講是足夠的,但是我沒有合理安排,有效的時間從一週變成了半周,時間變少,思考的時間變少,但是題目難度又沒變,因此寫的時候思路比較混亂。我應該合理安排時間,不能明知作業難度大還不慌不忙。
改進建議
TestPaperQuestion類在程式碼中未定義,但在TestPaper類中有引用,需要新增這個類。
GapFillingQuestion類沒有寫完,需要增加一些方法來實現更加複雜以及合理的邏輯。
ChoiceQuestion的getAnswers方法只支援單個答案,需要調整讓他支援多選。
TestPaper的getTotalScore方法依賴TestPaperQuestion的getScore方法,但這個方法沒有在程式碼中定義。
InputMatching類和DataWarehouse類寫的太過混亂,每個人的設計想法都是不同的,不能將別人的類設計強加到自己的設計中。
第五次作業 家居強電電路模擬程式-1
原始碼分析
設計思路
-
Device
類是所有電器裝置的父類:Device
抽象類定義了裝置的基本屬性和行為,包括編號、型別、輸入電壓、輸出電壓以及更新狀態的方法。getOutput方法用於獲取裝置的輸出,但具體實現依賴於子類。updateState 是一個抽象方法,由子類實現,以更新裝置的狀態(例如輸出電壓)。 -
具體裝置類:
控制裝置
Switch
、SteppedSpeedController
、ContinuousSpeedController
和受控裝置IncandescentLamp
、FluorescentLamp
和CeilingFan
是Device
的子類,它們實現了特定裝置的行為。每個子類都覆蓋了updateState
和getOutput
方法,以反映其特定的行為。裝置的行為,例如計算亮度、更新檔位等,都是在updateState
方法中實現的。 -
電路模擬器類 (
CircuitSimulator
):CircuitSimulator
類負責管理裝置,包括連線裝置、應用控制命令和應用電壓。connectDevices方法解析使用者輸入的連線資訊,並建立相應的裝置例項。applyControlCommand方法解析使用者輸入的控制命令,並應用到相應的裝置上。applyVoltage
方法類比電路行為,按順序設定每個裝置的輸入電壓,並更新它們的輸出狀態。
踩坑心得
1.一開始我將題目想的比較複雜,思路不夠簡化。這次的題目只有電路元件之間的串聯,並且不考慮電阻,但是在類設計時我總是想著之後該如何擴充套件導致寫的比較亂。後來在同學的指導下我逐漸理清思路,完成了作業。
2.在題目資訊比較多的情況下我喜歡將資訊以簡圖或者文字的形式整理在紙上,這樣看著比較清晰,防止資訊遺漏。
3.處理輸出時,程式沒有報錯但一直輸出不了。經過除錯後我發現不能只在子類中的方法重寫,我忘記在主類中呼叫相應的方法了。
4.這次作業的最後一個測試點沒有透過,但是沒有找到原因。這次是我的大作業完成的分數最高的一次,題目簡單佔一部分原因,另外還要感謝同學的幫助,耐心為我解答問題。
第六次作業 家居強電電路模擬程式-2
原始碼分析
設計思路
這次作業增加了一個受控裝置落地扇,增加了並聯的情況,還要考慮電阻。
首先要新寫一個落地扇類繼承風扇類。還要將串並聯分開,各自寫成一個類。SeriesCircuit
類表示一個串聯電路,包含一個裝置列表,透過組合多個Device
物件來模擬串聯電路的行為。ParallelCircuit
類表示一個並聯電路,包含一個串聯電路列表,透過組合多個SeriesCircuit
物件來模擬並聯電路的行為。
點選檢視程式碼
class SeriesCircuit extends Device {
private List<Device> devices = new ArrayList<>();
public SeriesCircuit(int number) {
super(number);
this.type = 8;
}
public List<Device> getDevices() {
return devices;
}
public void addDevice(Device device) {
devices.add(device);
}
@Override
public void updateState() {
if (devices.isEmpty()) {
return;
}
devices.get(0).setInputVoltage(inputVoltage);
devices.get(0).updateState();
for (int i = 1; i < devices.size(); i++) {
devices.get(i).setInputVoltage(devices.get(i - 1).getOutputVoltage());
devices.get(i).updateState();
}
setOutputVoltage(devices.get(devices.size() - 1).getOutputVoltage());
}
@Override
public void getOutput() {
for (Device device : devices) {
device.getOutput();
}
}
}
class ParallelCircuit extends Device {
private List<SeriesCircuit> circuits = new ArrayList<>();
public ParallelCircuit(int number) {
super(number);
this.type = 9;
}
public void addCircuit(SeriesCircuit circuit) {
circuits.add(circuit);
}
public List<SeriesCircuit> getCircuits() {
return circuits;
}
@Override
public void updateState() {
// if (circuits.isEmpty()) {
// return;
// }
for (SeriesCircuit circuit : circuits) {
circuit.setInputVoltage(inputVoltage);
circuit.updateState();
}
double totalCurrent = circuits.stream()
.mapToDouble(c -> c.getOutputVoltage() / c.getType())
.sum();
setOutputVoltage(inputVoltage);
}
@Override
public void getOutput() {
for (SeriesCircuit circuit : circuits) {
circuit.getOutput();
}
}
}
改進建議
這次的作業又一次沒有寫完,因為我實在是做不出來。
1.處理輸入時,在提取資訊的問題上我就遇到了困難,不知道如何將輸入的資訊提取出有效的部分並儲存起來。
2.我不知道怎麼將串聯電路和並聯電路合理地結合起來,這兩個類之間一定是有聯絡的但我不明白該如何實現。
3.我只是在裝置的屬性中設定了電阻的大小,但是整個電路的電阻我不知道應該以哪種方式儲存並計算出來。
4.這些問題都沒有得到及時的解決導致這次的作業寫起來非常困難。
總結
寫大作業的過程對我來說異常的煎熬,不理解,不明白,寫不出來的挫敗感是無法言說的。但是每有一點思路我都會盡力去寫,每處理好一部分問題的喜悅心情也是形容不出來的。我想到初中體育課上的蛙跳,老師說蛙跳就是把肌肉內的組織破壞又重構的過程,只有忍受疼痛不斷向前跳才能有最大的收穫。
我知道我的程式設計能力有限,在這方面的腦子不夠靈光,但是隻要堅持學習,每天有一點的進步也是好的。這門課程也快要結束了,希望我可以繼續堅持,提高效率,每週將實驗儘快完成就能留出更多的時間寫大作業。