OO第三次部落格
一、前言
目前已完成了九次題目集,本次部落格將對題目集7、8、9進行分析總結與反思。
很顯然本次題目集難度要高了很多,需要在題目上花費的時間也要多出很多,即使只有一道題,也是需要我們來進行仔細的思考與設計的。當然,經過一段時間的思考,我們就能解決掉很多問題。
題目集7所涉及到的知識點為類的繼承、多型性使用方法以及介面的應用,題目集8則重點考核類的封裝性及類間關係設計(關聯、組合及依賴),題目集9重點訓練內容為抽象類、繼承與多型。通過這三次實驗及考察的知識點可以看出,類的多型及封裝性在程式設計中十分重要。
二、設計與分析
1.題目集7(7-1)、(7-2)兩道題目的遞進式設計分析總結
這兩道題目與之前寫過的圖形繼承等題目有著很多相似的地方,其核心還是考察對於圖形類的各種處理方式。
跟之前最大的不同就是使用到了Comparable 介面以及其中的 CompareTo()方法。這個方法就是將指定的數與引數比大小,根據不同情況返回1、0、-1,從而方便進行後續操作,大大增加了我們的程式碼簡潔度。
interface Comparable{ public int compareTo(Card card); }
shape類繼承後將compareTo方法完善後程式碼:
public int compareTo(Card card) { return-(int)(shape.getArea()-card.getShape().getArea()); }
兩道題目也很相似,一道排序,一道分組,實際上分組也是在排序的基礎上進行的,也就是所謂的遞進式設計,先將圖片繼承設計出來,隨後設計排序,然後在此基礎上進行分組設計,能夠很大程度上改善程式碼的結構,讓設計更加清晰合理,也方便思考。
在排序設計的時候一開始沒有看到下方給出的類圖,因此結構十分混亂,也沒有什麼頭緒,導致設計出來的程式碼常常是拆東牆補西牆一樣的,這裡解決了那裡又出現了問題。在一次延時後,我才發現後面給出的類圖,重新對程式碼進行設計處理,才有了現在的程式。
7-1的圈複雜度↑
7-2的圈複雜度↑
現在寫程式碼和以前相比已經好了很多,基本上不會出現複雜度大於10的情況了,相比以前結構也有了很大的改善。
這兩道題目的類圖與給出的類圖相同,說明類設計符合要求。
2.題目集8和題目集9兩道ATM機模擬題目的設計思路分析總結
這兩道題目都是關於ATM機的問題,其中由於題目集8是我第一次接觸,導致我在設計的時候依然十分混亂,各種關係也沒能夠分析完善,導致類間關係混亂,並且也不符合生活實際。
能夠從類圖中看出來,各種關係,比如銀聯、使用者、賬戶、銀行卡之間的關係是混亂的,根本不符合生活邏輯,因此寫出來的程式碼十分雜亂無章。
而題目集九則是在老師給出的程式碼基礎上再進行修改,因此類間關係就相對明瞭,也明顯更加舒服,能很清楚的看出各種結構以及實體之間的關係。
三、採坑心得及改進建議
1.題目集7
這兩道題都是在圖形繼承基礎上進行的,因此也算是比較熟悉了,在實體類方面已經算是處理的得心應手了,不過在處理排序方面由於一開始沒有注意看要求以及指導冊,導致設計比較混亂,arraylist也沒用到幾次,還沒有用到正處。由於後面題目集又開放了一次,最初混亂的版本也沒有存下來,因此不在這裡貼出來了。
在網上尋找參考的時候,我看到很多人使用了Collections方法,我便去找了它的使用方法,一開始我看見了Collections.sort()方法,能夠直接對list進行排序,可當我實際使用進去的時候,會一直顯示報錯,因此我只能使用Collections.swap()方法,交換前後的位置,計算機在處理的時候可能會更麻煩一點。
public void cardSort() { for(int i = 0; i < cardList.size(); i ++) { for(int j = i + 1; j < cardList.size(); j ++){ if(cardList.get(i).getShape().getArea() < cardList.get(j).getShape().getArea()) Collections.swap(cardList, i, j); } System.out.print(cardList.get(i).getShape()); } }
原理上看起來就和以前學過的氣泡排序、選擇排序等排序方法一樣,不過將前後兩個元素交換的過程簡化了,可以看出還是十分方便的。
改進建議:儘可能解決掉Collections.sort()方法出現錯誤的問題,在此基礎上進一步簡化程式碼。
2.題目集8
在一開始寫ATM的時候,我並沒有認真的分析各種類之間的結構,導致了我寫出來的程式碼結構十分不堪入目。
class UnionPay { //銀聯 Bank bank; ArrayList<Card> car =new ArrayList<>(); public UnionPay() { super(); // TODO Auto-generated constructor stub } public ArrayList<Card> getCar() { return car; } public void setCar(ArrayList<Card> car) { this.car = car; } public void setUser() {//初始化使用者 } } class Card { private String cardNumber; private double balance = 10000.00; private String code = "88888888"; Account account; public Card() { super(); // TODO Auto-generated constructor stub account = new Account(); } } class Account { private String Account; User user; Bank bank; public Account() { super(); // TODO Auto-generated constructor stub } } class Agent {//代理類 private String card0; private String atm1; private String code; private double money; private UnionPay unionPay; private ATM atm; private Borrow borrow; private Save save; private Card card; public Agent() { super(); // TODO Auto-generated constructor stub } }
已省略部分程式碼,僅展示類間呼叫關係
一開始我以為銀聯才是最終的控制終端,因此將所有使用者的資訊都存進了銀聯之中,然後再一層層的向下呼叫,ATM機反而和銀行沒有了關聯。看到老師的程式碼我才發現各種呼叫關係的正確使用方法。
在使用我雜亂的程式碼提交成功後,我發現有很多測試點都沒有通過。
然後在後來我嘗試修改的時候就發現我設計錯誤導致我修改的各種麻煩,有點時候死活都找不出邏輯問題,但他確實存在錯誤,但是已經來不及了,大體結構已經定了下來,除非重新寫一個新的程式。
改進建議:調整類間關係,處理好實體類的上下級關係。在寫程式碼之前先分析每個實體之間的關係,以免後續關係混亂,導致程式碼修改困難。
3.題目集9
一開始拿到題目我還是有點手足無措的,雖然上一個題目集寫過,雖然有老師給的程式碼,但我還是對於這方面的理解有一點的弱了,因此看到更復雜的題目還是會不知道從哪裡去下手。
在分析老師的程式碼過後,我決定先從使用者增加下手,走一步看一步,在原本銀行的基礎上增加了新的銀行,增加了新的ATM機,以及新的使用者。
Bank ccb = new Bank("1001","中國建設銀行"); Bank icbc = new Bank("1002","中國工商銀行"); Bank abc = new Bank("1003","中國農業銀行"); unionPay.addBank(ccb); unionPay.addBank(icbc); unionPay.addBank(abc);
新增加的銀行
ATM aTM7 = new ATM("07",abc); ATM aTM8 = new ATM("08",abc); ATM aTM9 = new ATM("09",abc); ATM aTM10 = new ATM("10",abc); ATM aTM11 = new ATM("11",abc);
abc.addATM(aTM7);
abc.addATM(aTM8);
abc.addATM(aTM9);
abc.addATM(aTM10);
abc.addATM(aTM11);
新增的ATM機
User Zhangsanfeng = new User("360345600512434223","張三丰","13025686987"); User Linghuchong = new User("360805600578963578","令狐沖","13825345632"); User Qiaofeng = new User("360905600514567923","喬峰","13325098987"); User Hongqigong = new User("360905600576567653","洪七公","13924345436"); Account ccbDcc1 = new Account("3640000010045442002",10000.00,Zhangsanfeng,ccb,1); Account icbcDcc1 = new Account("3640000010045441009",10000.00,Linghuchong,icbc,1); Account abcDcc1 = new Account("3630000010033431001",10000.00,Qiaofeng,abc,1); Account abcDcc2 = new Account(" 3630000010033431008",10000.00,Hongqigong,abc,1); ccb.addAccount(ccbDcc1); icbc.addAccount(icbcDcc1); abc.addAccount(abcDcc1); abc.addAccount(abcDcc2); Zhangsanfeng.addAccount(ccbDcc1); Linghuchong.addAccount(icbcDcc1); Qiaofeng.addAccount(abcDcc1); Hongqigong.addAccount(abcDcc2); Card ccbCard11 = new Card("6640000010045442002","88888888",ccbDcc1); Card ccbCard12 = new Card("6640000010045442003","88888888",ccbDcc1); Card icbcCard13 = new Card("6640000010045441009","88888888",icbcDcc1); Card abcCard14 = new Card("6630000010033431001","88888888",abcDcc1); Card abcCard15 = new Card("6630000010033431008","88888888",abcDcc2); ccbDcc1.addCard(ccbCard11); ccbDcc1.addCard(ccbCard12); icbcDcc1.addCard(icbcCard13); abcDcc1.addCard(abcCard14); abcDcc2.addCard(abcCard15);
新增的使用者程式碼
因為增加了貸記卡,因此在賬戶上進行區分,我一開始並沒有區分,導致後面貸款操作出現了錯誤,甚至無法識別貸記卡或是借記卡,因此我在每個賬戶後面添加了區分,使用1或者0進而區分是貸記卡或是借記卡,從而方便後續判斷。
由於一開始忽略了合法輸入的判斷,因此每次測試貸記卡或者跨行的時候資料都會報錯。
後來還和舍友討論了關於稅率的問題,在我認識裡,取出來的錢是已經扣過稅後的錢,但感覺好像有有些不對勁,當時改了挺多次的,一直卡在借記卡跨行取出所有錢後到底是什麼樣的。誰想到最後問過別的同學之後發現原來要報出資料錯誤,而不是計算,畢竟要取的錢加稅收要比原來賬戶有的錢多嘛。
果然在使用老師改進之後的程式碼後,各種改動也都順暢了許多,儘管還有部分點沒有通過
以後也要爭取向這方面去發展!
改進建議:完善程式碼,解決剩餘問題,找出所說部分問題,儘量調整。
四、總結
通過這幾次的題目集,更讓我對於類的繼承設計有了進一步的瞭解,也讓我對於類間關係的重要性有了進一步的認識,沒有一個良好的類間關係,會對整體程式碼、程式的執行造成很大的障礙,也會使後續維護與改進變的困難。今後在寫程式碼之前要先判斷好各種實體之間的關係,然後設計好每個類直接的關係後再進性後續寫程式碼的操作,以防造成更多不可逆轉的損失。
通過這幾次題目集的訓練,我對於ArrayList的使用也有了進一步的認識,它不僅僅是簡單的陣列或是連結串列一樣的東西,能夠將其靈活應用將會對後續的各種操作帶來極大的便利。
同時這幾次的題目也讓我認識到我所學習的遠遠不夠,我需要更多的知識來提高我個人的能力,增強競爭力。不能光侷限於書上所學,多想身邊的人學習,多想其他人學習,遇到不會的及時去解決,這樣才能不斷的進步,不斷的去積累知識。
我知道自己還存在許多的不足,經常在題目集結束之後才找到解決錯誤的方法,還需提高自己的學習效率,以及加強與老師同學的溝通,我也意識到了有時候一個人的力量是有限的,與人溝通的時候往往能夠拓寬思路,找到新的解決方案。在今後的學習中,我要以更加積極的態度去面對困難與挫折,不逃避,也要改掉自己的壞毛病。
千里之行,始於足下,什麼時候開始都不算晚!