PTA題目集7-9總結
一、前言
題目集七:該題集為輪到圖形卡片排序遊戲題,主要考查的知識點有類的繼承,ArrayList泛型的使用,Compabale介面的運用,多型的使用方法以及介面的應用,難度較難,題量適中;
題目集八:這個題集都為一道ATM機類結構設計題,主要考查的知識點有各實體類之間的關係,尤其是一對多的組合關係。對實體類的設計要做到單一職責原則,且不能缺少規定的實體類。程式設計時考慮物件導向中的封裝性本題目中的應用以及是否有能夠擴充套件 的衍生需求。對我來說這道題難度很大,開始有點無從下手,有太多的組合和關聯,讓我邏輯很混亂。
題目集九:這個題集都為一道ATM機類結構設計題,主要考查的知識點有各實體類之間的關係,尤其是一對多的組合關係。對實體類的設計要做到單一職責原則,且不能缺少規定的實體類。在“合成複用原則”及“單一職責原則”基礎上,儘量對上次作業的程 序進行重構,使之符合 “開-閉”原則。在題集八的基礎上,題集九就稍微更簡單了一些,但是還是很有難度,但相比於題集八思路清晰了許多。
二、設計與分析
(1):題目集七(7-1)
類圖及複雜分析圖如下:
本題要求考慮一款適合於小學生的卡片(Card)排序遊戲,其規則為隨機發放一些卡片給學生,卡片分為 四種形狀:圓形(Circle)、矩形(Rectangle)、三角形(Triangle)及梯形(Trapezoid),並給出各種 卡片的相應引數,要求學生能夠迅速求出各卡片的面積大小然後將卡片按照其面積值從大到小進行排 序,同時求出所有卡片的面積之和。
為實現該要求,先建立Shape抽象類,類中有構造方法,得到,設定圖形名字的方法,計算面積方法,判斷是否合法方法和toString方法;然後建立Circle,Rectangle,Triangle,Trapezoid這四個類,然後這四個類都繼承Shape類,然後重寫Shape類中的方法;建立Card類,Card類關聯Shape類,shape類作為Card類的屬性,Card類中有他的構造方法和得到圖形的方法以及比較方法;最後建立DealCardList類,DealCardList類關聯Card類,DealCardList類中使用ArrayList泛型,將圖片物件放入該陣列列表中;主要實現了對面積的計算,排序以及對同型別的面積求和功能。
各類的建立:
class Card { Shape shape; Card() { } public Card(Shape shape) { // super(); this.shape = shape; } public Shape getShape() { return shape; } public void setShape(Shape shape) { this.shape = shape; } } abstract class Shape { String shapeName; Shape() { } public Shape(String shapeName) { this.shapeName = shapeName; } public String getShapeName() { return shapeName; } public void setShapeName(String shapeName) { this.shapeName = shapeName; } public abstract double getArea(); public abstract boolean validate(); public abstract String toString(); } class Circle extends Shape { private double radius; Circle() { } public Circle(double radius) { this.radius = radius; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } @Override public double getArea() { // TODO Auto-generated method stub return Math.PI * radius * radius; } @Override public boolean validate() { // TODO Auto-generated method stub if (radius < 0) return false; else return true; } @Override public String toString() { // TODO Auto-generated method stub return "Circle:"; } } class Rectangle extends Shape { private double width; private double length; Rectangle() { } public Rectangle(double width, double length) { super(); this.width = width; this.length = length; } public double getWidth() { return width; } public void setWidth(double width) { this.width = width; } public double getLength() { return length; } public void setLength(double length) { this.length = length; } @Override public double getArea() { // TODO Auto-generated method stub return width * length; } @Override public boolean validate() { // TODO Auto-generated method stub if (width < 0 | length < 0) return false; else return true; } @Override public String toString() { // TODO Auto-generated method stub return "Rectangle:"; } } class Triangle extends Shape { private double side1; private double side2; private double side3; Triangle() { } public Triangle(double side1, double side2, double side3) { super(); this.side1 = side1; this.side2 = side2; this.side3 = side3; } public double getSide1() { return side1; } public void setSide1(double side1) { this.side1 = side1; } public double getSide2() { return side2; } public void setSide2(double side2) { this.side2 = side2; } public double getSide3() { return side3; } public void setSide3(double side3) { this.side3 = side3; } @Override public double getArea() { // TODO Auto-generated method stub double i = (side1 + side2 + side3) / 2.0; return Math.sqrt(i * (i - side1) * (i - side2) * (i - side3)); } @Override public boolean validate() { // TODO Auto-generated method stub double[] side = { side1, side2, side3 }; Arrays.sort(side); if (side1 <= 0 | side2 <= 0 | side3 <= 0 | side[0] + side[1] <= side[2] | side[2] - side[1] >= side[0]) return false; else return true; } @Override public String toString() { // TODO Auto-generated method stub return "Triangle:"; } } class Trapezoid extends Shape { double topSide; double bottomSide; double height; Trapezoid() { } public Trapezoid(double topSide, double bottomSide, double height) { super(); this.topSide = topSide; this.bottomSide = bottomSide; this.height = height; } public double getTopSide() { return topSide; } public void setTopSide(double topSide) { this.topSide = topSide; } public double getBottomSide() { return bottomSide; } public void setBottomSide(double bottomSide) { this.bottomSide = bottomSide; } public double getHeight() { return height; } public void setHeight(double height) { this.height = height; } @Override public double getArea() { // TODO Auto-generated method stub return (topSide + bottomSide) * height / 2.0; } @Override public boolean validate() { // TODO Auto-generated method stub if (topSide < 0 | bottomSide < 0 | height < 0) return false; else return true; } @Override public String toString() { // TODO Auto-generated method stub return "Trapezoid:"; } }
建立好各類後,在主函式中建立一個物件陣列,將所輸入的圖形資料等都放入圖形陣列中,便於在後續的使用:
ArrayList<Shape> shape = new ArrayList<>();
for (int i = 0; i < list.size(); i++) { if (list.get(i) == 1) { double radius = in.nextDouble(); Shape circle = new Circle(radius); shape.add(circle); } if (list.get(i) == 2) { double width = in.nextDouble(); double length = in.nextDouble(); Shape rectangle = new Rectangle(width, length); shape.add(rectangle); } if (list.get(i) == 3) { double side1 = in.nextDouble(); double side2 = in.nextDouble(); double side3 = in.nextDouble(); Shape triangle = new Triangle(side1, side2, side3); shape.add(triangle); } if (list.get(i) == 4) { double topSide = in.nextDouble(); double bottomSide = in.nextDouble(); double height = in.nextDouble(); Shape trapezoid = new Trapezoid(topSide, bottomSide, height); shape.add(trapezoid); } }
(2)題目集七(7-2)
類圖及複雜分析圖如下:
在7-2中,沿襲作業 7-1,本次作業主要對卡片(Card)進行分組遊戲,其規則為隨機發放一些卡片給學生, 卡片仍然分為四種形狀:圓形(Circle)、矩形(Rectangle)、三角形(Triangle)及梯形(Trapezoid), 並給出各種卡片的相應引數,要求學生首先根據卡片型別將所有卡片進行分組(一個型別分為一組, 所以最多四組),然後能夠對每組內的卡片根據面積值從大到小進行排序,同時求出該組內所有卡片 的面積之和,最後求出每組卡片面積之和中的最大值。
該題與7-1不同的是,7-2中需要首先根據卡片型別將所有卡片進行分組,然後分別將這四種圖形存入四個ArrayList()陣列列表中,然後將輸入的圖形放入到各自相對應的陣列列表中,然後再通過對各個列表的面積進行排序和求總面積,這樣就能求出每組卡片的面積值的排序和該組內所有卡片面積之和以及相對應的組中的面積之和的最大值。其他類中大部分都沒有改動。
建立四個圖形的物件陣列,將輸入的圖形資料按照不同的圖形放入不同的物件陣列中去:
ArrayList<Shape> shape = new ArrayList<>(); ArrayList<Circle> circle1 = new ArrayList<>(); ArrayList<Rectangle> rectangle1 = new ArrayList<>(); ArrayList<Triangle> triangle1 = new ArrayList<>(); ArrayList<Trapezoid> trapezoid1 = new ArrayList<>(); if(num==0) { System.out.println("Wrong Format"); System.exit(0); } while (num != 0) { if (num < 0 || num > 4) { System.out.println("Wrong Format"); System.exit(0); } list.add(num); num = in.nextInt(); } for (int i = 0; i < list.size(); i++) { if (list.get(i) == 1) { double radius = in.nextDouble(); Shape circle = new Circle(radius); shape.add(circle); circle1.add((Circle) circle); } if (list.get(i) == 2) { double width = in.nextDouble(); double length = in.nextDouble(); Shape rectangle = new Rectangle(width, length); shape.add(rectangle); rectangle1.add((Rectangle) rectangle); } if (list.get(i) == 3) { double side1 = in.nextDouble(); double side2 = in.nextDouble(); double side3 = in.nextDouble(); Shape triangle = new Triangle(side1, side2, side3); shape.add(triangle); triangle1.add((Triangle) triangle); } if (list.get(i) == 4) { double topSide = in.nextDouble(); double bottomSide = in.nextDouble(); double height = in.nextDouble(); Shape trapezoid = new Trapezoid(topSide, bottomSide, height); shape.add(trapezoid); trapezoid1.add((Trapezoid) trapezoid); } } for (int i = 0; i < shape.size(); i++) { if (shape.get(i).validate() == false) { System.out.println("Wrong Format"); System.exit(0); } }
比較方法使用Compare方法:
//列印圓 System.out.println("The Separated sorted List:"); System.out.print("["); circle1.stream().sorted((u1,u2)->{return Double.compare(u2.getArea(),u1.getArea());}) .forEach(u1->{System.out.printf("Circle:%.2f ", u1.getArea());}); System.out.print("]"); //列印矩形 System.out.print("["); rectangle1.stream().sorted((u1,u2)->{return Double.compare(u2.getArea(),u1.getArea());}) .forEach(u1->{System.out.printf("Rectangle:%.2f ", u1.getArea());}); System.out.print("]"); //列印三角形 System.out.print("["); triangle1.stream().sorted((u1,u2)->{return Double.compare(u2.getArea(),u1.getArea());}) .forEach(u1->{System.out.printf("Triangle:%.2f ", u1.getArea());}); System.out.print("]"); //列印梯形 System.out.print("["); trapezoid1.stream().sorted((u1,u2)->{return Double.compare(u2.getArea(),u1.getArea());}) .forEach(u1->{System.out.printf("Trapezoid:%.2f ", u1.getArea());}); System.out.print("]");
(3)習題八
複雜分析圖如下:
習題八為編寫一個銀行 ATM 機的模擬程式,能夠完成使用者的存款、取款以及查詢餘額功能。嘗試使用物件導向技術對銀行使用者在 ATM 機上進行相關操作的模擬系統設 計,上述的相關概念均要設計為實體類,業務(控制)類請自行根據實際需要進 行擴充和完善。本次作業限定銀行卡均為借記卡(不能透支),且不允許跨行辦理相關業務(例如在中國建設銀行的 ATM 機上對其他銀行的賬戶進行操作。
初始化資料:將所給的資料都分別存放入不同的陣列中
static String[] CardNum = { "6217000010041315709", "6217000010041315715", "6217000010041315718", "6217000010051320007", "6222081502001312389", "6222081502001312390", "6222081502001312399", "6222081502001312400", "6222081502051320785", "6222081502051320786" }; static String[] BankNum = { "中國建設銀行", "中國建設銀行", "中國建設銀行", "中國建設銀行", "中國工商銀行", "中國工商銀行", "中國工商銀行", "中國工商銀行", "中國工商銀行", "中國工商銀行" }; static String[] AtmNum = { "01", "02", "03", "04", "05", "06" }; static String[] name = { "楊過", "楊過", "楊過", "郭靖", "張無忌", "張無忌", "張無忌", "張無忌", "韋小寶", "韋小寶" }; static String[] AccountNum = { "3217000010041315709", "3217000010041315709", "3217000010041315715", "3217000010051320007", "3222081502001312389", "3222081502001312390", "3222081502001312399", "3222081502001312399", "3222081502051320785", "3222081502051320785" };
使用HashMap進行儲存資料和HashSet實現set集合
HashMap<String,Account> map = new HashMap<>(); Set<String> set = new HashSet<>(); Account lastAccount=null; for(int i=0;i<name.length;i++) { if(set.contains(AccountNum[i])) map.put(CardNum[i], lastAccount); else { Account account = new Account(BankNum[i],AccountNum[i],name[i],10000.00); map.put(CardNum[i], account); set.add(AccountNum[i]); lastAccount=account; } }
建立各銀行,賬戶,使用者類等,然後進行一一對比判斷。
(4)習題九
類圖及複雜分析圖如下:
編寫一個銀行 ATM 機的模擬程式,能夠完成使用者的取款以及查詢餘額功能。嘗試使用物件導向技術對銀行使用者在 ATM 機上進行相關操作的模擬系統設計,上述的相關概念均要設計為實體類,業務(控制)類請自行根據實際需要進 行擴充和完善。本次作業中銀行卡包含借記卡和信用卡兩類,且允許跨行辦理相關業 務(例如在中國建設銀行的 ATM 機上使用中國工商銀行的銀行卡進行業務操作)。
通過上一次作業中老師的講解,有了更清晰的思路,本題與上一題的區別是增加了更多功能,增加了貸記卡即可超額借款,可以跨賬戶轉賬,但需要考慮手續費,利息和超額借款的限度等,對於本題先是初始化資料,然後對各個類中的資料進行一一巢狀,然後判斷是什麼卡,是否跨行,是否超過了借款限度,手續費和利息等等;
在一開始我不懂得怎麼初始化資料,尤其是如何讓一個資料裡面可以有另一個資料的資訊,然後經過老師對程式碼的講解就明白了,可以在建立物件對他初始化,相比於上一次程式碼,在初始化資料時需要增加銀行,賬戶,使用者等,同時可以在初始化Bank時就將每個銀行所對應的利率加入進去,同時在初始化Card時,增加每張卡的屬性是借記卡還是貸記卡,在後面判斷卡時更好操作;在瞭解設計的背景後知道有哪些實體類要設計並且要知道比如賬號,密碼等資訊究竟是屬於那個類的屬性,然後設計了UnionPay、Bank、ATM、User、Account、Card這些類,並且各個有關係的類之間用ArrayList連線在一起 2.業務類:拿老師的例子來說有GetBalance、ValidateData、Withdraw來實現餘額的查詢,存、取錢等功能。
UnionPay unionPay = new UnionPay(); Bank ccb = new Bank("1001","中國建設銀行",0.02); Bank icbc = new Bank("1002","中國工商銀行",0.03); Bank nc = new Bank("1003","中國農業銀行",0.04); unionPay.addBank(ccb); unionPay.addBank(icbc); unionPay.addBank(nc); ATM aTM1 = new ATM("01",ccb); ATM aTM2 = new ATM("02",ccb); ATM aTM3 = new ATM("03",ccb); ATM aTM4 = new ATM("04",ccb); ATM aTM5 = new ATM("05",icbc); ATM aTM6 = new ATM("06",icbc); ATM aTM7 = new ATM("07",nc); ATM aTM8 = new ATM("08",nc); ATM aTM9 = new ATM("09",nc); ATM aTM10 = new ATM("10",nc); ATM aTM11 = new ATM("11",nc); ccb.addATM(aTM1); ccb.addATM(aTM2); ccb.addATM(aTM3); ccb.addATM(aTM4); icbc.addATM(aTM5); icbc.addATM(aTM6); nc.addATM(aTM7); nc.addATM(aTM8); nc.addATM(aTM9); nc.addATM(aTM10); nc.addATM(aTM11); User Yangguo = new User("360101200102122324","楊過"); User Guojing = new User("360101200012302552","郭靖"); User Zhangwuji = new User("360502199805163221","張無忌"); User Weixiaobao = new User("360201200513243326","韋小寶"); User zhangsanfeng = new User("3640000010045442002","張三丰"); User linghuchong = new User("3640000010045441009","令狐沖"); User qiaofeng = new User("3630000010033431001 ","喬峰"); User hongqigong = new User("3630000010033431008","洪七公"); Account ccbAcc1 = new Account("3217000010041315709",10000.00,Yangguo,ccb); Account ccbAcc2 = new Account("3217000010041315715",10000.00,Yangguo,ccb); Account ccbAcc3 = new Account("3217000010051320007",10000.00,Guojing,ccb); Account ccbAcc4 = new Account("3640000010045442002",10000.00,zhangsanfeng,ccb); Account icbcAcc1 = new Account("3222081502001312389",10000.00,Zhangwuji,icbc); Account icbcAcc2 = new Account("3222081502001312390",10000.00,Zhangwuji,icbc); Account icbcAcc3 = new Account("3222081502001312399",10000.00,Zhangwuji,icbc); Account icbcAcc4 = new Account("3222081502051320785",10000.00,Weixiaobao,icbc); Account icbcAcc5 = new Account("3222081502051320786",10000.00,Weixiaobao,icbc); Account icbcAcc6 = new Account("3640000010045441009",10000.00,linghuchong,icbc); Account ncAcc1 = new Account("3630000010033431001",10000.00,qiaofeng,nc); Account ncAcc2 = new Account("3630000010033431008",10000.00,hongqigong,nc); ccb.addAccount(ccbAcc1); ccb.addAccount(ccbAcc2); ccb.addAccount(ccbAcc3); ccb.addAccount(ccbAcc4); icbc.addAccount(icbcAcc1); icbc.addAccount(icbcAcc2); icbc.addAccount(icbcAcc3); icbc.addAccount(icbcAcc4); icbc.addAccount(icbcAcc5); nc.addAccount(ncAcc1); nc.addAccount(ncAcc2); Yangguo.addAccount(ccbAcc1); Yangguo.addAccount(ccbAcc2); Guojing.addAccount(ccbAcc3); zhangsanfeng.addAccount(ccbAcc4); Zhangwuji.addAccount(icbcAcc1); Zhangwuji.addAccount(icbcAcc2); Zhangwuji.addAccount(icbcAcc3); Weixiaobao.addAccount(icbcAcc4); linghuchong.addAccount(icbcAcc5); qiaofeng.addAccount(ncAcc1); hongqigong.addAccount(ncAcc2); Card ccbCard1 = new Card("6217000010041315709","88888888",ccbAcc1,"借記賬號"); Card ccbCard2 = new Card("6217000010041315715","88888888",ccbAcc1,"借記賬號"); Card ccbCard3 = new Card("6217000010041315718","88888888",ccbAcc2,"借記賬號"); Card ccbCard4 = new Card("6217000010051320007","88888888",ccbAcc3,"借記賬號"); Card icbcCard5 = new Card("6222081502001312389","88888888",icbcAcc1,"借記賬號"); Card icbcCard6 = new Card("6222081502001312390","88888888",icbcAcc2,"借記賬號"); Card icbcCard7 = new Card("6222081502001312399","88888888",icbcAcc3,"借記賬號"); Card icbcCard8 = new Card("6222081502001312400","88888888",icbcAcc3,"借記賬號"); Card icbcCard9 = new Card("6222081502051320785","88888888",icbcAcc4,"借記賬號"); Card icbcCard10 = new Card("6222081502051320786","88888888",icbcAcc4,"借記賬號"); Card ccbCard11 = new Card("6640000010045442002","88888888",ccbAcc4,"貸記賬號"); Card ccbCard12 = new Card("6640000010045442003","88888888",ccbAcc4,"貸記賬號"); Card icbcCard13 = new Card("6640000010045441009","88888888",icbcAcc5,"貸記賬號"); Card ncCard14 = new Card("6630000010033431001","88888888",ncAcc1,"貸記賬號"); Card ncCard15 = new Card("6630000010033431008","88888888",ncAcc2,"貸記賬號"); ccbAcc1.addCard(ccbCard1); ccbAcc1.addCard(ccbCard2); ccbAcc2.addCard(ccbCard3); ccbAcc3.addCard(ccbCard4); icbcAcc1.addCard(icbcCard5); icbcAcc2.addCard(icbcCard6); icbcAcc3.addCard(icbcCard7); icbcAcc3.addCard(icbcCard8); icbcAcc4.addCard(icbcCard9); icbcAcc5.addCard(icbcCard10); ccbAcc4.addCard(ccbCard11); ccbAcc4.addCard(ccbCard12); icbcAcc6.addCard(icbcCard13); ncAcc1.addCard(ncCard14); ncAcc2.addCard(ncCard15);
在Withdraw類中對所有情況進行考慮和判斷
public class Withdraw { private UnionPay unionPay; private String cardNO; private String cardPassword; private String ATMID; private double amount; private String type; public Withdraw() { super(); // TODO Auto-generated constructor stub } public Withdraw(UnionPay unionPay,String cardNO, String cardPassword, String aTMID, double amount) { super(); this.unionPay = unionPay; this.cardNO = cardNO; this.cardPassword = cardPassword; ATMID = aTMID; this.amount = amount; } public Withdraw(String cardNO, String cardPassword, String aTMID, double amount, String type) { super(); this.cardNO = cardNO; this.cardPassword = cardPassword; ATMID = aTMID; this.amount = amount; this.type = type; } public void withdraw() { /** * 校驗該卡是否存在 */ Card card = ValidateData.getCardbyCardNO(unionPay, cardNO); if (card == null) { System.out.println("Sorry,this card does not exist."); System.exit(0); } /** * 校驗ATM是否存在 */ ATM aTM = ValidateData.getATMbyATMID(unionPay, ATMID); if (aTM == null) { System.out.println("Sorry,the ATM's id is wrong."); System.exit(0); } Account account = Account.getAmountbyCardNO(cardNO); double balance = account.getBalance(); /** * 校驗卡密碼是否正確 */ if (!card.getCardPassword().equals(cardPassword)) { System.out.println("Sorry,your password is wrong."); System.exit(0); } double rate1=0.05; //跨行取款 if(account.getBank().getBankNO() != aTM.getBank().getBankNO()) { if(card.getType().equals("貸記賬號")) { //不透支 if(balance-amount>0) balance=balance - ValidateData.getBankbyATMID(unionPay, ATMID).getRate()*amount; //透支 else { if(balance-amount<-50000) { System.out.println("Sorry,your account balance is insufficient."); System.exit(0); } if(balance>0) balance=balance-ValidateData.getBankbyATMID(unionPay, ATMID).getRate()*amount-(amount-balance)*rate1; else balance=balance-ValidateData.getBankbyATMID(unionPay, ATMID).getRate()*amount-amount*rate1; //透支取款後判斷是否還能透支 } } if(card.getType().equals("借記賬號")) { //正常取款 balance=balance - ValidateData.getBankbyATMID(unionPay, ATMID).getRate()*amount; //超額取款 }if(balance<amount) { System.out.println("Sorry,your account balance is insufficient."); System.exit(0); } } //不跨行 else { if(card.getType().equals("借記賬號")) { balance=balance; } if(card.getType().equals("貸記賬號")) { //不透支 if(balance-amount>0) balance=balance; //透支 else { if(balance>0) balance=balance-(amount-balance)*rate1; else balance=balance-amount*rate1; //透支取款後判斷是否還能透支 if(balance-amount<-50000) { System.out.println("Sorry,your account balance is insufficient."); System.exit(0); } } } } //更新餘額 account.setBalance(balance - amount); if (amount >= 0) { showResult(account, "Y"); } else { showResult(account, "N"); } } //跨行取款 public void showResult(Account account, String flag1) { Card card = ValidateData.getCardbyCardNO(unionPay, cardNO); String type1 = ""; if (flag1 == "Y") { type1 = "取款"; } if (flag1 == "N") { type1 = "存款"; amount *= -1; } String userName = account.getUser().getName(); //String bankName = account.getBank().getBankName(); System.out.println("業務:" + type1 + " " + userName + "在" + ValidateData.getBankbyATMID(unionPay, ATMID).getBankName() + "的" + ATMID + "號ATM機上" + type1 + String.format("¥%.2f", amount)); System.out.println("當前餘額為" + String.format("¥%.2f", account.getBalance())); } }
為通過卡號獲取該賬戶所在的銀行,ATM機,ATM機編號建立了一個ValidateData類,首先先通過迭代器進行遍歷校對卡號,然後在對需要判斷的再次進行迭代遍歷判斷
public class ValidateData { public static Card getCardbyCardNO(UnionPay unionPay,String cardNO) { Card card = null; Iterator<Bank> bankItr = unionPay.getBankList().iterator(); while(bankItr.hasNext()) { // ArrayList<Account> accountList = bankItr.next().getAccountList(); Iterator<Account> accountItr = accountList.iterator(); while(accountItr.hasNext()) { ArrayList<Card> cardList = accountItr.next().getList(); Iterator<Card> cardItr = cardList.iterator(); while(cardItr.hasNext()) { card = cardItr.next(); // if(card.getCardNO().equals(cardNO)) { return card; } } } } return null; } /** * 校驗ATM ID是否存在 * @param unionPay * @param ATMID * @return */ public static ATM getATMbyATMID(UnionPay unionPay,String ATMID) { Iterator<Bank> bankItr = unionPay.getBankList().iterator(); Bank bank = null; ATM aTM = null; while(bankItr.hasNext()) { bank = bankItr.next(); Iterator<ATM> aTMItr = bank.getATMList().iterator(); while(aTMItr.hasNext()) { aTM = aTMItr.next(); if(aTM.getATMID().equals(ATMID)) { return aTM; } } } return null; } public static Bank getBankbyATMID(UnionPay unionPay,String ATMID) { Iterator<Bank> bankItr = unionPay.getBankList().iterator(); Bank bank = null; ATM aTM = null; while(bankItr.hasNext()) { bank = bankItr.next(); Iterator<ATM> aTMItr = bank.getATMList().iterator(); while(aTMItr.hasNext()) { aTM = aTMItr.next(); if(aTM.getATMID().equals(ATMID)) { return aTM.getBank(); } } } return null; } }
題目集8用於設計一個簡單的ATM機功能,功能作用在:簡單的存取款與查詢餘額。設計的背景為:中國銀聯,中國銀行,銀行使用者,銀行賬戶,銀行卡,ATM機。各個組成部分,都可以實現為一個實體類。各個實體類之間有一定的關聯性。
對於題目集9,功能更全面複雜,如:能夠完成使用者的取款以及查詢餘額功能。銀行賬戶分為借記賬戶和貸記賬戶兩種,其中,借記賬戶不能夠透支 取款,而貸記賬戶可以透支取款(可能需要支付手續費)。且允許跨行辦理相關業 務。考察的依舊是:繼承,多型,抽象類,類間關係設計以及對於“開-閉”原則,單一職責原則的掌握。
跟題目集8的7-1有所不同的是新增一種信用卡,可以進行貸記操作,以及銀聯有了超額度的服務費扣取功能,跨行收費。主類中都是根據正規表示式以及if語句決定功能走向的分支。不同點在於會在題目集9的程式碼中不同的銀行新增不同的利率屬性,在業務類中新增對跨行後的收費處理以及透支判斷等。以上都是對特定功能的新增,需要考慮到類設計的“開-閉”原則,單一職責原則。以及迭代到的不僅是相同背景內容的功能新增,更有考慮到類間關係,去充分利用實體類的屬性繫結以及方法呼叫。業務類中整合方法去實現最終輸出的效果。本次ATM機迭代程式設計,本身邏輯層面簡單,注重的是嚴謹的設計思想與正確的物件導向程式設計思維。
二、踩坑心得
1:在習題七的7-2中,因為我將不同的圖形放置於不同的物件陣列導致如果我要使用CompareTo的話就會比較麻煩,需要每一個類中都再增加此方法,為了更加簡潔在同學的幫助下學會了lamba表示式,簡潔有效,其次如果我開始將四種圖形放在同一個物件陣列中再使用CompareTo可能不會走這麼多彎路;
circle1.sort((u1,u2)->{return Double.compare(u1.getArea(), u2.getArea());}); rectangle1.sort((u1,u2)->{return Double.compare(u1.getArea(), u2.getArea());}); triangle1.sort((u1,u2)->{return Double.compare(u1.getArea(), u2.getArea());}); trapezoid1.sort((u1,u2)->{return Double.compare(u1.getArea(), u2.getArea());});
2:在7-2提交時因程式碼長度過長無法提交程式碼,程式碼較累贅,後為了提交只得刪減空行,刪減註釋,以及將可放在一行的程式碼儘量放在一行內等,這樣的話雖然能夠通過了,但是在視覺上看起來還是有點不太美觀,因此以後寫程式碼時還是應該多思考怎麼能更簡潔,高效一些;
3:在習題九中,對於借貸時沒有注意他只是超過了的那部分才需要乘以利息導致開始時的資料總是錯誤,後注意到後修改了計算方法;
4:超過了額度的錢才可以被取出,所寫的判斷沒有起到作用,同時當跨行取出全部金額時,因為要扣除跨行費用本應該不能取出,但是他卻可以繼續取,後發現所寫的順序有點混亂後重新寫了跨行和超額取款部分
//跨行取款 if(account.getBank().getBankNO() != aTM.getBank().getBankNO()) { if(card.getType().equals("貸記賬號")) { //不透支 if(balance-amount>0) balance=balance - ValidateData.getBankbyATMID(unionPay, ATMID).getRate()*amount; //透支 else { if(balance-amount<-50000) { System.out.println("Sorry,your account balance is insufficient."); System.exit(0); } if(balance>0) balance=balance-ValidateData.getBankbyATMID(unionPay, ATMID).getRate()*amount-(amount-balance)*rate1; else balance=balance-ValidateData.getBankbyATMID(unionPay, ATMID).getRate()*amount-amount*rate1; //透支取款後判斷是否還能透支 } } if(card.getType().equals("借記賬號")) { //正常取款 balance=balance - ValidateData.getBankbyATMID(unionPay, ATMID).getRate()*amount; //超額取款 }if(balance<amount) { System.out.println("Sorry,your account balance is insufficient."); System.exit(0); } }
二、改進建議
在習題七和八中對於輸出都寫的很複雜,基本同樣的程式碼重複寫了四遍,太過重複,可以單獨寫一個方法來寫輸出程式碼,減少重複;同時應該充分提高程式碼的複用性,並且儘可能提升程式碼的安全性,並做好封裝,此外如果業務類要實現的功能很多,應該儘可能細化,實現單一性原則和開閉原則。
二、總結
通過本階段的學習,總體來說鍛鍊的就是在設計的時候還要考慮多種類的特性,開閉原則和單一性原則,然後就是作業雖然有難度但是學到的東西也很多,比如通過這次ATM機的類設計,慢慢的貼近現實生活,在類設計之前也會考慮很多現實生活中的問題,感覺學習程式設計更有意思了一些,但通過這幾次遊戲和ATM機的設計也讓我體會到了程式設計的難度,我還需要繼續學習多多學習。