前言:
最近一段时间学习的习题均意在让我们加深了解类的继承、多态性使用方法等等面对对象编程的特性。并且通过试题还了解到了一些编程的基本原则与java中的集合框架,通过习题的实践还让我了解到了合理设计类与合理设计类的功能的重要性。
7-1
考虑一款适合于小学生的卡片(Card)排序游戏,其规则为随机发放一些卡片给学生,卡片分为四种形状:圆形(Circle)、矩形(Rectangle)、三角形(Triangle)及梯形(Trapezoid),并给出各种卡片的相应参数,要求学生能够迅速求出各卡片的面积大小然后将卡片按照其面积值从大到小进行排序,同时求出所有卡片的面积之和。
输入格式:
- 在一行上输入一串数字(1~4,整数),其中,1代表圆形卡片,2代表矩形卡片,3代表三角形卡片,4代表梯形卡片。各数字之间以一个或多个空格分隔,以“0”结束。例如:
1 3 4 2 1 3 4 2 1 3 0
- 根据第一行数字所代表的卡片图形类型,依次输入各图形的相关参数,例如:圆形卡片需要输入圆的半径,矩形卡片需要输入矩形的宽和长,三角形卡片需要输入三角形的三条边长,梯形需要输入梯形的上底、下底以及高。各数据之间用一个或多个空格分隔。
输出格式:
- 如果图形数量非法(<=0)或图形属性值非法(数值<0以及三角形三边不能组成三角形),则输出
Wrong Format
。 - 如果输入合法,则正常输出,所有数值计算后均保留小数点后两位即可。输出内容如下:
- 排序前的各图形类型及面积,格式为
[图形名称1:面积值1图形名称2:面积值2 …图形名称n:面积值n ]
,注意,各图形输出之间用空格分开,且输出最后存在一个用于分隔的空格,在结束符“]”之前; - 输出分组后的图形类型及面积,格式为
[圆形分组各图形类型及面积][矩形分组各图形类型及面积][三角形分组各图形类型及面积][梯形分组各图形类型及面积]
,各组内格式为图形名称:面积值
。按照“Circle、Rectangle、Triangle、Trapezoid”的顺序依次输出; - 各组内图形排序后的各图形类型及面积,格式同排序前各组图形的输出;
- 各组中面积之和的最大值输出,格式为
The max area:面积值
参考类图:
不同形状均继承Shape,在card类中依赖了一个Shape类型的对象,由于各种形状都继承Shape于是该变量可以表示任意一个形状,体现了多态性。
做为抽象类的shape类,其中定义了得到面积getarea方法的,用来检验输入数据是否正确的validate方法,还有重写了object类的就是tostring方法,继承了他的子类,就可以利用这些方法来检测自身数据是否合理,或者重写方法得到面积,卡类依赖了一个shape类,通过实现接口可以使得它可以简单排序。
由题目可知要求依据面积对几个形状的 进行排序,可以用collections的sort方法对一个列表的元素进行快速排序,为了让列表中的元素依照指定的方式进行排序使Card类实现comparable接口并重写接口方法,依据面积进行排序。
@Override public int compareTo(Card o) { // TODO 自动生成的方法存根 if(shape.getArea()>o.getShape().getArea()) return -1; if(shape.getArea()==o.getShape().getArea()) return 0; if(shape.getArea()<o.getShape().getArea()) return 1; return 0; } }
在习题7-2中要求
输入的图形按照图形类型进行分组并输出
输出格式:
- 如果图形数量非法(<=0)或图形属性值非法(数值<0以及三角形三边不能组成三角形),则输出
Wrong Format
。 - 如果输入合法,则正常输出,所有数值计算后均保留小数点后两位即可。输出内容如下:
- 排序前的各图形类型及面积,格式为
[图形名称1:面积值1图形名称2:面积值2 …图形名称n:面积值n ]
,注意,各图形输出之间用空格分开,且输出最后存在一个用于分隔的空格,在结束符“]”之前; - 输出分组后的图形类型及面积,格式为
[圆形分组各图形类型及面积][矩形分组各图形类型及面积][三角形分组各图形类型及面积][梯形分组各图形类型及面积]
,各组内格式为图形名称:面积值
。按照“Circle、Rectangle、Triangle、Trapezoid”的顺序依次输出; - 各组内图形排序后的各图形类型及面积,格式同排序前各组图形的输出;
- 各组中面积之和的最大值输出,格式为
The max area:面积值
。
可知只需要在对各个相同的图形类做一个合并就可以,可以格外设立多个列表装入相同形状的对象如何利用sort方法就可以做到快速排序。
1 ArrayList<Card> carlist=new ArrayList<>(); 2 ArrayList<Card> listOfci=new ArrayList<>(); 3 ArrayList<Card> listOfjuxing=new ArrayList<>(); 4 ArrayList<Card> listOfsjx=new ArrayList<>(); 5 ArrayList<Card> listOftixing=new ArrayList<>(); 6 DealCardList(ArrayList<Integer> list){ 7 for(int i=0;i<list.size();i++) { 8 if(list.get(i)==1) { 9 Circle ci=new Circle(Main.input.nextDouble()); 10 carlist.add(new Card(ci)); 11 listOfci.add(carlist.get(i)); 12 } 13 if(list.get(i)==2) { 14 cfx cf=new cfx(Main.input.nextDouble(), Main.input.nextDouble()); 15 carlist.add(new Card(cf)); 16 listOfjuxing.add(carlist.get(i)); 17 } 18 if(list.get(i)==3) { 19 carlist.add(new Card(new sjx(Main.input.nextDouble(), Main.input.nextDouble(),Main.input.nextDouble()))); 20 listOfsjx.add(carlist.get(i));} 21 if(list.get(i)==4) { 22 23 carlist.add(new Card(new tixing(Main.input.nextDouble(), Main.input.nextDouble(), Main.input.nextDouble()))); 24 listOftixing.add(carlist.get(i)); 25 } 26 } 27
7-1 7-2 Atm类设计
1.作业目标编写一个银行ATM机的模拟程序,能够完成用户的存款、取款以及查询余额功能。
输入格式:
每一行输入一次业务操作,可以输入多行,最终以字符#终止。具体每种业务操作输入格式如下:
- 存款、取款功能输入数据格式:
卡号 密码 ATM机编号 金额
(由一个或多个空格分隔), 其中,当金额大于0时,代表取款,否则代表存款。 - 查询余额功能输入数据格式:
卡号
本次作业中银行卡包含借记卡和信用卡两类,且允许跨行办理相关业务,借记业务与跨行取款业务均需要手续费。
手续费默认均从银行卡所对应的账户中自动扣除。
跨行业务手续费收取比例由ATM机隶属银行决定,例如,用户手持中国工商银行的银行卡在中国建设银行的ATM上进行取款操作,则手续费收取比例为中国建设银行的相应比例,按初始化数据中的规定为取款金额的2%。
跨行查询余额不收取手续费。
透支取款手续费由中国银联统一规定为5%,最大透支金额均为50000元
类图:
可知程序的一切功能都由UnionPay进入,程序的数据初始化由InitDate类来完成,模拟的借记操作由Withdraw类来完成,下面放上代码。
1 package Ptatext; 2 3 import java.util.ArrayList; 4 import java.util.Iterator; 5 import java.util.Scanner; 6 import java.util.regex.Matcher; 7 import java.util.regex.Pattern; 8 9 /** 10 * 账户抽象类 11 * 12 * @author Administrator 13 * @date 14 */ 15 abstract class AbstractAccount { 16 private String accountNO;// 账号 17 private double balance = 0;// 余额 18 private User user = null;// 用户 19 private Bank bank = null;// 所属银行 20 private double ratio = 0;// 透支取款手续费 21 private double overdrawAmount = 0;// 可透支金额 22 private static ArrayList<Card> list = new ArrayList<Card>(); 23 24 public AbstractAccount() { 25 super(); 26 // TODO Auto-generated constructor stub 27 } 28 29 public AbstractAccount(String accountNO, double balance, User user, Bank bank, double ratio, 30 double overdrawAmount) { 31 super(); 32 this.accountNO = accountNO; 33 this.balance = balance; 34 this.user = user; 35 this.bank = bank; 36 this.ratio = ratio; 37 this.overdrawAmount = overdrawAmount; 38 } 39 40 public String getAccountNO() { 41 return accountNO; 42 } 43 44 public void setAccountNO(String accountNO) { 45 this.accountNO = accountNO; 46 } 47 48 public double getBalance() { 49 return balance; 50 } 51 52 public void setBalance(double balance) { 53 this.balance = balance; 54 } 55 56 public User getUser() { 57 return user; 58 } 59 60 public void setUser(User user) { 61 this.user = user; 62 } 63 64 public double getOverdrawAmount() { 65 return overdrawAmount; 66 } 67 68 public void setOverdrawAmount(double overdrawAmount) { 69 this.overdrawAmount = overdrawAmount; 70 } 71 72 public Bank getBank() { 73 return bank; 74 } 75 76 public void setBank(Bank bank) { 77 this.bank = bank; 78 } 79 80 public double getRatio() { 81 return ratio; 82 } 83 84 public void setRatio(double ratio) { 85 this.ratio = ratio; 86 } 87 88 public static ArrayList<Card> getList() { 89 return list; 90 } 91 92 public static void setList(ArrayList<Card> list) { 93 AbstractAccount.list = list; 94 } 95 96 public void addCard(Card card) { 97 list.add(card); 98 } 99 100 public void removeCard(Card card) { 101 list.remove(card); 102 } 103 } 104 105 /** 106 * ATM机类 107 * 108 * @author Administrator 109 * @date 110 */ 111 class ATM { 112 private String ATMID; 113 private Bank bank = null;// ATM所隶属银行 114 115 public ATM() { 116 super(); 117 // TODO Auto-generated constructor stub 118 } 119 120 public ATM(String aTMID, Bank bank) { 121 super(); 122 ATMID = aTMID; 123 this.bank = bank; 124 } 125 126 public String getATMID() { 127 return ATMID; 128 } 129 130 public void setATMID(String aTMID) { 131 ATMID = aTMID; 132 } 133 134 public Bank getBank() { 135 return bank; 136 } 137 138 public void setBank(Bank bank) { 139 this.bank = bank; 140 } 141 } 142 143 /** 144 * 工具类,和上次程序不同处之一,希望大家思考下该类的作用 145 * 146 * @author Administrator 147 * @date 148 */ 149 class ATMUtil { 150 /** 151 * 根据卡号获取银行卡,卡号正确则返回卡对象,否则返回null 152 * 153 * @param unionPay 154 * @param cardNO 155 * @return 156 */ 157 public static Card getCardbyCardNO(UnionPay unionPay, String cardNO) { 158 Card card = null; 159 Iterator<Bank> bankItr = unionPay.getBankList().iterator(); 160 161 while (bankItr.hasNext()) { 162 ArrayList<AbstractAccount> accountList = bankItr.next().getAccountList(); 163 Iterator<AbstractAccount> accountItr = accountList.iterator(); 164 while (accountItr.hasNext()) { 165 ArrayList<Card> cardList = accountItr.next().getList(); 166 Iterator<Card> cardItr = cardList.iterator(); 167 while (cardItr.hasNext()) { 168 card = cardItr.next(); 169 if (card.getCardNO().equals(cardNO)) { 170 return card; 171 } 172 } 173 } 174 } 175 return null; 176 } 177 178 /** 179 * 根据ATM ID求得ATM对象,如果ID正确则返回ATM对象,否则返回null 180 * 181 * @param unionPay 182 * @param ATMID 183 * @return 184 */ 185 public static ATM getATMbyATMID(UnionPay unionPay, String ATMID) { 186 Iterator<Bank> bankItr = unionPay.getBankList().iterator(); 187 Bank bank = null; 188 ATM aTM = null; 189 190 while (bankItr.hasNext()) { 191 bank = bankItr.next(); 192 Iterator<ATM> aTMItr = bank.getATMList().iterator(); 193 194 while (aTMItr.hasNext()) { 195 aTM = aTMItr.next(); 196 if (aTM.getATMID().equals(ATMID)) { 197 return aTM; 198 } 199 } 200 } 201 return null; 202 } 203 204 /** 205 * 根据卡号获取改卡所隶属的账号,若卡号正确,则返回账号对象,否则返回null 206 * 207 * @param cardNO 208 * @return 209 */ 210 public static AbstractAccount getAccountbyCardNO(String cardNO) { 211 Iterator<Card> cardItr = AbstractAccount.getList().iterator(); 212 Card card = null; 213 214 while (cardItr.hasNext()) { 215 card = cardItr.next(); 216 if (card.getCardNO().equals(cardNO)) { 217 return card.getAccount(); 218 } 219 } 220 return null; 221 } 222 } 223 224 /** 225 * 银行类 226 * 227 * @author Administrator 228 * @date 229 */ 230 class Bank { 231 private String bankNO;// 银行编号 232 private String bankName;// 银行名称 233 private double commission;// 跨行业务收取的手续费 234 // 银行拥有的账户列表 235 private ArrayList<AbstractAccount> accountList = new ArrayList<AbstractAccount>(); 236 // 银行拥有的ATM机列表 237 private ArrayList<ATM> ATMList = new ArrayList<ATM>(); 238 239 public Bank() { 240 super(); 241 // TODO Auto-generated constructor stub 242 } 243 244 public Bank(String bankNO, String bankName, double commission) { 245 super(); 246 this.bankNO = bankNO; 247 this.bankName = bankName; 248 this.commission = commission; 249 } 250 251 public String getBankNO() { 252 return bankNO; 253 } 254 255 public void setBankNO(String bankNO) { 256 this.bankNO = bankNO; 257 } 258 259 public String getBankName() { 260 return bankName; 261 } 262 263 public void setBankName(String bankName) { 264 this.bankName = bankName; 265 } 266 267 public double getCommission() { 268 return commission; 269 } 270 271 public void setCommission(double commission) { 272 this.commission = commission; 273 } 274 275 public void addAccount(AbstractAccount account) { 276 this.accountList.add(account); 277 } 278 279 public void removeAccount(AbstractAccount account) { 280 this.accountList.remove(account); 281 } 282 283 public void addATM(ATM aTM) { 284 this.ATMList.add(aTM); 285 } 286 287 public void removeATM(ATM aTM) { 288 this.ATMList.remove(aTM); 289 } 290 291 public ArrayList<AbstractAccount> getAccountList() { 292 return accountList; 293 } 294 295 public void setAccountList(ArrayList<AbstractAccount> accountList) { 296 this.accountList = accountList; 297 } 298 299 public ArrayList<ATM> getATMList() { 300 return ATMList; 301 } 302 303 public void setATMList(ArrayList<ATM> aTMList) { 304 ATMList = aTMList; 305 } 306 } 307 308 /** 309 * 银行卡类,大家思考下该类与账户类的关系,例如用户的余额为什么不是设置在Card类中 310 * 311 * @author Administrator 312 * @date 313 */ 314 class Card { 315 private String cardNO;// 卡号 316 private String cardPassword;// 密码 317 private AbstractAccount account = null;// 该卡所属账号 318 319 public Card() { 320 super(); 321 // TODO Auto-generated constructor stub 322 } 323 324 public Card(String cardNO, String cardPassword, AbstractAccount account) { 325 super(); 326 this.cardNO = cardNO; 327 this.cardPassword = cardPassword; 328 this.account = account; 329 } 330 331 public String getCardNO() { 332 return cardNO; 333 } 334 335 public void setCardNO(String cardNO) { 336 this.cardNO = cardNO; 337 } 338 339 public String getCardPassword() { 340 return cardPassword; 341 } 342 343 public AbstractAccount getAccount() { 344 return account; 345 } 346 347 public void setAccount(AbstractAccount account) { 348 this.account = account; 349 } 350 351 public void setCardPassword(String cardPassword) { 352 this.cardPassword = cardPassword; 353 } 354 355 public boolean checkCard() { 356 Pattern p = Pattern.compile("\\d{16}+"); 357 Matcher m = p.matcher(this.cardNO); 358 return m.matches(); 359 } 360 361 public boolean checkPassword(String password) { 362 return this.cardPassword.equals(password); 363 } 364 365 } 366 367 /** 368 * 信用卡类,继承自抽象账户类 369 * 370 * @author Administrator 371 * @date 372 */ 373 class CreditAccount extends AbstractAccount { 374 375 public CreditAccount() {// 贷记账户 376 super(); 377 // TODO Auto-generated constructor stub 378 this.setRatio(0.05); 379 } 380 381 public CreditAccount(String accountNO, double balance, User user, Bank bank, double ratio, double overdrawAmount) { 382 super(accountNO, balance, user, bank, 0.05, 50000.00);// 这是取巧但并不好的一种设计,大家思考下 383 // TODO Auto-generated constructor stub 384 } 385 } 386 387 /** 388 * 借记卡类,继承自抽象账户类 389 * 390 * @author Administrator 391 * @date 2021/06/12 392 */ 393 class DebitAccount extends AbstractAccount {// 借记账户 394 395 public DebitAccount() { 396 super(); 397 this.setRatio(0); 398 // TODO Auto-generated constructor stub 399 } 400 401 public DebitAccount(String accountNO, double balance, User user, Bank bank, double ratio, double overdrawAmount) { 402 super(accountNO, balance, user, bank, 0, 0.00);// 同信用卡类的设计 403 // TODO Auto-generated constructor stub 404 } 405 } 406 407 /** 408 * 业务类,查询余额 409 * 410 * @author Administrator 411 * @date 412 */ 413 class GetBalance { 414 private UnionPay unionPay;// UnionPay类为一切业务类的入口 415 416 public GetBalance() { 417 super(); 418 // TODO Auto-generated constructor stub 419 } 420 421 public GetBalance(UnionPay unionPay) { 422 super(); 423 this.unionPay = unionPay; 424 } 425 426 public double getBalance(String cardNO) { 427 return ATMUtil.getCardbyCardNO(unionPay, cardNO).getAccount().getBalance(); 428 } 429 } 430 431 /** 432 * 数据初始化类 433 * 434 * @author Administrator 435 * @date 436 */ 437 class InitData { 438 439 public InitData() { 440 // TODO Auto-generated constructor stub 441 } 442 443 public static UnionPay initData() { 444 UnionPay unionPay = new UnionPay(); 445 446 Bank ccb = new Bank("1001", "中国建设银行", 0.02); 447 Bank icbc = new Bank("1002", "中国工商银行", 0.03); 448 Bank abc = new Bank("1003", "中国农业银行", 0.04);// new 449 unionPay.addBank(ccb); 450 unionPay.addBank(icbc); 451 unionPay.addBank(abc);// new 452 453 ATM aTM1 = new ATM("01", ccb); 454 ATM aTM2 = new ATM("02", ccb); 455 ATM aTM3 = new ATM("03", ccb); 456 ATM aTM4 = new ATM("04", ccb); 457 ATM aTM5 = new ATM("05", icbc); 458 ATM aTM6 = new ATM("06", icbc); 459 ATM aTM7 = new ATM("07", abc);// new 460 ATM aTM8 = new ATM("08", abc);// new 461 ATM aTM9 = new ATM("09", abc);// new 462 ATM aTM10 = new ATM("10", abc);// new 463 ATM aTM11 = new ATM("11", abc);// new 464 465 ccb.addATM(aTM1); 466 ccb.addATM(aTM2); 467 ccb.addATM(aTM3); 468 ccb.addATM(aTM4); 469 icbc.addATM(aTM5); 470 icbc.addATM(aTM6); 471 abc.addATM(aTM7);// new 472 abc.addATM(aTM8);// new 473 abc.addATM(aTM9);// new 474 abc.addATM(aTM10);// new 475 abc.addATM(aTM11);// new 476 477 User Yangguo = new User("360101200102122324", "杨过", "13856223254"); 478 User Guojing = new User("360101200012302552", "郭靖", "13800021124"); 479 User Zhangwuji = new User("360502199805163221", "张无忌", "13952110011"); 480 User Weixiaobao = new User("360201200513243326", "韦小宝", "13025996587"); 481 User Zhangsanfeng = new User("360102199713459810", "张三丰", "13677871290");// new 482 User Linghuchong = new User("360503190299878473", "令狐冲", "13609899238");// new 483 User Qiaofeng = new User("360607194313666711", "乔峰", "13677871290");// new 484 User Hongqigong = new User("363220987809872234", "洪七公", "13609009454");// new 485 486 AbstractAccount ccbAcc1 = new DebitAccount("3217000010041315709", 10000.00, Yangguo, ccb, 0, 0); 487 AbstractAccount ccbAcc2 = new DebitAccount("3217000010041315715", 10000.00, Yangguo, ccb, 0, 0); 488 AbstractAccount ccbAcc3 = new DebitAccount("3217000010051320007", 10000.00, Guojing, ccb, 0, 0); 489 AbstractAccount ccbAcc4 = new CreditAccount("3640000010045442002", 10000.00, Zhangsanfeng, ccb, 0.05, 50000.00);// new 490 491 AbstractAccount icbcAcc1 = new DebitAccount("3222081502001312389", 10000.00, Zhangwuji, icbc, 0, 0); 492 AbstractAccount icbcAcc2 = new DebitAccount("3222081502001312390", 10000.00, Zhangwuji, icbc, 0, 0); 493 AbstractAccount icbcAcc3 = new DebitAccount("3222081502001312399", 10000.00, Zhangwuji, icbc, 0, 0); 494 AbstractAccount icbcAcc4 = new DebitAccount("3222081502051320785", 10000.00, Weixiaobao, icbc, 0, 0); 495 AbstractAccount icbcAcc5 = new DebitAccount("3222081502051320786", 10000.00, Weixiaobao, icbc, 0, 0); 496 AbstractAccount icbcAcc6 = 497 new CreditAccount("3640000010045441009", 10000.00, Linghuchong, icbc, 0.05, 50000.00);// new 498 499 AbstractAccount abcAcc1 = new CreditAccount("3630000010033431001", 10000.00, Qiaofeng, abc, 0.05, 50000.00);// new 500 AbstractAccount abcAcc2 = new CreditAccount("3630000010033431008", 10000.00, Hongqigong, abc, 0.05, 50000.00);// new 501 502 ccb.addAccount(ccbAcc1); 503 ccb.addAccount(ccbAcc2); 504 ccb.addAccount(ccbAcc3); 505 ccb.addAccount(ccbAcc4);// new 506 507 icbc.addAccount(icbcAcc1); 508 icbc.addAccount(icbcAcc2); 509 icbc.addAccount(icbcAcc3); 510 icbc.addAccount(icbcAcc4); 511 icbc.addAccount(icbcAcc5); 512 icbc.addAccount(icbcAcc6);// new 513 514 abc.addAccount(abcAcc1);// new 515 abc.addAccount(abcAcc2);// new 516 517 Yangguo.addAccount(ccbAcc1); 518 Yangguo.addAccount(ccbAcc2); 519 Guojing.addAccount(ccbAcc3); 520 Zhangsanfeng.addAccount(ccbAcc4);// new 521 522 Zhangwuji.addAccount(icbcAcc1); 523 Zhangwuji.addAccount(icbcAcc2); 524 Zhangwuji.addAccount(icbcAcc3); 525 Weixiaobao.addAccount(icbcAcc4); 526 Weixiaobao.addAccount(icbcAcc5); 527 Linghuchong.addAccount(icbcAcc6);// new 528 529 Qiaofeng.addAccount(abcAcc1);// new 530 Hongqigong.addAccount(abcAcc2);// new 531 532 Card ccbCard1 = new Card("6217000010041315709", "88888888", ccbAcc1); 533 Card ccbCard2 = new Card("6217000010041315715", "88888888", ccbAcc1); 534 Card ccbCard3 = new Card("6217000010041315718", "88888888", ccbAcc2); 535 Card ccbCard4 = new Card("6217000010051320007", "88888888", ccbAcc3); 536 537 Card icbcCard5 = new Card("6222081502001312389", "88888888", icbcAcc1); 538 Card icbcCard6 = new Card("6222081502001312390", "88888888", icbcAcc2); 539 Card icbcCard7 = new Card("6222081502001312399", "88888888", icbcAcc3); 540 Card icbcCard8 = new Card("6222081502001312400", "88888888", icbcAcc3); 541 Card icbcCard9 = new Card("6222081502051320785", "88888888", icbcAcc4); 542 Card icbcCard10 = new Card("6222081502051320786", "88888888", icbcAcc5); 543 544 Card ccbCard11 = new Card("6640000010045442002", "88888888", ccbAcc4);// new 545 Card ccbCard12 = new Card("6640000010045442003", "88888888", ccbAcc4);// new 546 547 Card icbcCard13 = new Card("6640000010045441009", "88888888", icbcAcc6);// new 548 549 Card abcCard14 = new Card("6630000010033431001", "88888888", abcAcc1);// new 550 Card abcCard15 = new Card("6630000010033431008", "88888888", abcAcc2);// new 551 552 ccbAcc1.addCard(ccbCard1); 553 ccbAcc1.addCard(ccbCard2); 554 ccbAcc2.addCard(ccbCard3); 555 ccbAcc3.addCard(ccbCard4); 556 ccbAcc4.addCard(ccbCard11);// new 557 ccbAcc4.addCard(ccbCard12);// new 558 559 icbcAcc1.addCard(icbcCard5); 560 icbcAcc2.addCard(icbcCard6); 561 icbcAcc3.addCard(icbcCard7); 562 icbcAcc3.addCard(icbcCard8); 563 icbcAcc4.addCard(icbcCard9); 564 icbcAcc5.addCard(icbcCard10); 565 icbcAcc6.addCard(icbcCard13);// new 566 567 abcAcc1.addCard(abcCard14);// new 568 abcAcc2.addCard(abcCard15);// new 569 570 return unionPay; 571 } 572 } 573 574 /** 575 * 银联类 576 * 577 * @author Administrator 578 * @date 579 */ 580 class UnionPay { 581 private ArrayList<Bank> bankList = new ArrayList<Bank>();// 银联包含的银行列表 582 583 public UnionPay() { 584 super(); 585 // TODO Auto-generated constructor stub 586 } 587 588 public UnionPay(ArrayList<Bank> bankList) { 589 super(); 590 this.bankList = bankList; 591 } 592 593 public ArrayList<Bank> getBankList() { 594 return bankList; 595 } 596 597 public void setBankList(ArrayList<Bank> bankList) { 598 this.bankList = bankList; 599 } 600 601 public void addBank(Bank bank) { 602 this.bankList.add(bank); 603 } 604 605 public void removeBank(Bank bank) { 606 this.bankList.remove(bank); 607 } 608 } 609 610 /** 611 * 用户类 612 * 613 * @author Administrator 614 * @date 615 */ 616 class User { 617 private String ID;// 身份证号 618 private String name;// 姓名 619 private String Phone;// 电话号码 620 ArrayList<AbstractAccount> list = new ArrayList<AbstractAccount>();// 该用户拥有的账户列表(注意,账户可能隶属于不同银行 621 622 public User() { 623 super(); 624 // TODO Auto-generated constructor stub 625 } 626 627 public User(String iD, String name, String phone) { 628 super(); 629 ID = iD; 630 this.name = name; 631 Phone = phone; 632 } 633 634 public String getID() { 635 return ID; 636 } 637 638 public void setID(String iD) { 639 ID = iD; 640 } 641 642 public String getPhone() { 643 return Phone; 644 } 645 646 public void setPhone(String phone) { 647 Phone = phone; 648 } 649 650 public String getName() { 651 return name; 652 } 653 654 public void setName(String name) { 655 this.name = name; 656 } 657 658 public void addAccount(AbstractAccount ccbAcc1) { 659 this.list.add(ccbAcc1); 660 } 661 662 public void removeAccount(DebitAccount account) { 663 this.list.remove(account); 664 } 665 } 666 667 /** 668 * 业务类,取款类 669 * 670 * @author Administrator 671 * @date 672 */ 673 class Withdraw { 674 // 以下属性为取款需要输入的信息 675 private UnionPay unionPay;// 银联,一切业务操作的入口 676 private String cardNO;// 卡号 677 private String cardPassword;// 密码 678 private String ATMID;// ATM编号 679 private double amount;// 取款金额 680 681 // 根据卡号获取卡对象 682 private Card card = null; 683 // 根据ATM编号获取ATM对象 684 private ATM aTM = null; 685 // 根据卡号获取对应账号 686 private AbstractAccount account = null; 687 // 根据ATM或ATM所属银行对象 688 private Bank bank = null; 689 690 public Withdraw() { 691 super(); 692 // TODO Auto-generated constructor stub 693 } 694 695 /** 696 * 697 * @param unionPay 698 * @param cardNO 699 * @param cardPassword 700 * @param aTMID 701 * @param amount 702 */ 703 public Withdraw(UnionPay unionPay, String cardNO, String cardPassword, String aTMID, double amount) { 704 super(); 705 this.unionPay = unionPay; 706 this.cardNO = cardNO; 707 this.cardPassword = cardPassword; 708 ATMID = aTMID; 709 this.amount = amount; 710 } 711 712 /** 713 * 求跨行业务手续费 714 * 715 * @return 716 */ 717 public double getCrossBankCommission(double amount) { 718 return amount * bank.getCommission(); 719 } 720 721 /** 722 * 求透支取款手续费 723 * 724 * @param amount 725 * @return 726 */ 727 public double getOverdrawCommission(double amount) { 728 return amount * account.getRatio(); 729 } 730 731 /** 732 * 校验是否为跨行取款 733 */ 734 public boolean isCrossBank() { 735 if (account.getBank().getBankNO() != aTM.getBank().getBankNO()) { 736 return true; 737 } 738 return false; 739 } 740 741 /** 742 * 判断是否为信用卡 743 * 744 * @return 745 */ 746 public boolean isCreditAccount() { 747 if (account instanceof CreditAccount) { 748 return true; 749 } 750 return false; 751 } 752 753 /** 754 * 校验输入的数据是否正确 注意:该方法不支持开闭原则,大家可以思考如何设计才能针对各种银行卡均能够实现开闭原则 755 * 756 * @return 757 */ 758 public boolean checkData() { 759 760 // 获取银行卡对象 761 card = ATMUtil.getCardbyCardNO(unionPay, cardNO); 762 763 // 银行卡不存在(卡号错误) 764 if (card == null) { 765 System.out.println("Sorry,this card does not exist."); 766 return false; 767 } 768 769 // 获取ATM机对象 770 aTM = ATMUtil.getATMbyATMID(unionPay, ATMID); 771 772 // ATM机不存在(ATM ID错误) 773 if (aTM == null) { 774 System.out.println("Sorry,the ATM's id is wrong."); 775 return false; 776 } 777 778 // 获取ATM机所隶属银行对象 779 bank = aTM.getBank(); 780 781 // 用户密码错误 782 if (!card.getCardPassword().equals(cardPassword)) { 783 System.out.println("Sorry,your password is wrong."); 784 return false; 785 } 786 787 // 根据卡号获取用户账号 788 account = ATMUtil.getAccountbyCardNO(cardNO); 789 790 // 如果为借记卡 791 if (!isCreditAccount()) { 792 double commission = 0; 793 794 // 如果为跨行业务,则收取跨行费用 795 if (this.isCrossBank()) { 796 commission += this.getCrossBankCommission(amount); 797 } 798 // 取款超出余额 799 if (amount + commission > account.getBalance()) { 800 System.out.println("Sorry,your account balance is insufficient."); 801 return false; 802 } 803 } 804 805 // 如果为信用卡 806 if (isCreditAccount()) { 807 double commission = 0; // 手续费总额 808 double overdrawAmount = 0; // 透支金额 809 double balance = 0; // 当前卡上余额 810 811 balance = account.getBalance(); // 获取当前卡余额 812 813 // 有余额,则透支金额为取款金额与余额的差值 814 if (balance >= 0) { 815 overdrawAmount = amount - account.getBalance(); 816 } else {// 余额为负值(已经透支),则透支金额为取款金额 817 overdrawAmount = amount; 818 } 819 820 // 收取跨行业务费用 821 if (this.isCrossBank()) { 822 commission += this.getCrossBankCommission(amount); 823 } 824 // 收取透支费用 825 if (overdrawAmount > 0) { 826 commission += this.getOverdrawCommission(overdrawAmount); 827 } 828 829 // 如果取款金额与手续费金额之和大于卡片余额与可透支最大金额之和,无法取款 830 if (commission + amount > account.getBalance() + account.getOverdrawAmount()) { 831 System.out.println("Sorry,your account balance is insufficient."); 832 return false; 833 } 834 } 835 836 return true; 837 } 838 839 /** 840 * 该方法支持开闭原则 841 */ 842 public void withdraw() { 843 double commission = 0; 844 double overdrawAmount = 0; 845 double balance = 0; 846 847 balance = account.getBalance(); 848 849 if (balance >= 0) { 850 overdrawAmount = amount - account.getBalance(); 851 } else { 852 overdrawAmount = amount; 853 } 854 855 // 收取跨行费用 856 if (this.isCrossBank()) { 857 commission += this.getCrossBankCommission(amount); 858 } 859 // 收取透支费用 860 if (overdrawAmount > 0) { 861 commission += this.getOverdrawCommission(overdrawAmount); 862 } 863 864 if (commission + amount > balance + account.getOverdrawAmount()) { 865 System.out.println("Sorry,your account balance is insufficient."); 866 System.exit(0); 867 } 868 869 this.account.setBalance(balance - amount - commission); 870 showResult(this.account); 871 } 872 873 /** 874 * 显示 875 * 876 * @param account 877 */ 878 public void showResult(AbstractAccount account) { 879 String userName = account.getUser().getName(); 880 String bankName = aTM.getBank().getBankName(); 881 System.out 882 .println("业务:取款 " + userName + "在" + bankName + "的" + ATMID + "号ATM机上取款" + String.format("¥%.2f", amount)); 883 884 System.out.println("当前余额为" + String.format("¥%.2f", account.getBalance())); 885 } 886 } 887 888 public class Atm类设计 { 889 public static void main(String[] args) { 890 Scanner input = new Scanner(System.in); 891 892 UnionPay unionPay = InitData.initData();// 初始化程序数据 893 894 StringBuilder sb = new StringBuilder();// 用于接收输入数据 895 896 String data; 897 898 // 解析输入各行数据 899 while (!((data = input.nextLine()).equals("#"))) { 900 sb.append(data + "\n"); 901 } 902 903 String[] dt = sb.toString().split("\n"); 904 for (int i = 0; i < dt.length; i++) { 905 String[] dataLine = dt[i].toString().split("\\s+"); 906 907 if (dataLine.length == 1) {// 查询余额功能 908 GetBalance gb = new GetBalance(unionPay); 909 System.out.println("业务:查询余额 " + String.format("¥%.2f", gb.getBalance(dataLine[0]))); 910 } else {// 取款功能 911 Withdraw wd = 912 new Withdraw(unionPay, dataLine[0], dataLine[1], dataLine[2], Double.parseDouble(dataLine[3])); 913 if (wd.checkData()) { 914 wd.withdraw(); 915 } else { 916 System.exit(0); 917 } 918 } 919 } 920 } 921 }View Code
在写这题的难处就在于各个功能如何去实现以及各个类如何去设计以及各个类之间的关系。就拿我之前的设计来说
class user{ String name; ArrayList<BankCount> mycount=new ArrayList<>();//我的银行账号 public user(String name) { this.name = name; } } class Yanguo extends user{ Yanguo(){ super("杨过"); BankCount one=new BankCount("中国建设银行","3217000010041315709"); one.cardnumb.add("6217000010041315709"); one.cardnumb.add("6217000010041315715"); BankCount two=new BankCount("中国建设银行", "3217000010041315715"); two.cardnumb.add("6217000010041315718"); mycount.add(one); mycount.add(two); } } class Guojin extends user{ public Guojin() { super("郭靖"); // TODO 自动生成的构造函数存根 BankCount one =new BankCount("中国建设银行","3217000010051320007"); one.cardnumb.add("6217000010051320007"); } } class ZhanWuji extends user{ public ZhanWuji() { super("张无忌"); // TODO 自动生成的构造函数存根 BankCount one=new BankCount("中国工商银行", "3222081502001312389"); one.cardnumb.add("6222081502001312389"); BankCount two=new BankCount("中国工商银行","3222081502001312390"); two.cardnumb.add("6222081502001312390"); BankCount three=new BankCount("中国工商银行", "3222081502001312399"); three.cardnumb.add("6222081502001312399"); three.cardnumb.add("6222081502001312400"); mycount.add(one); mycount.add(two); mycount.add(three); } }
每个人(user)设计为一个类,明显不符合类的设计标准,以及设计功能时以简略为主,没有考虑到类的设计原则,导致代码看起来杂乱难以看懂。
总结:
通过在这几次的作业和课堂中我更加了解了java中类设计的原则,如
1、内聚性
类应该被描述为一个单一的实体,而所有的类操作应该在逻辑上相互配合,支持一个一致的目的。
2、一致性
遵循标准java程序设计风格和命名习惯,为类、数据域和方法选取具有信息的名字,通常风格是将数据域的声明置于构造方法之前,将构造方法置于方法之前,而对于在多个类中执行相同工作的方法,应该用同一个名字。
3、封装性
一个类应该用private修饰符隐藏数据域,以免用户直接访问它,这使得类更易于维护,只有在希望数据可读的情况下才提供get方法,希望数据可更新的情况下才提供set方法。
4、清晰性
用户可以以各种不同组合、顺序、以及在各种环境中结合使用多个类,因此在设计一个类时,这个类不应该限制用户如何以及何时使用该类,方法应在不产生混淆的情况下直观定义,不应该声明一个来自其他数据域的数据域。
5、要用类名来引用静态变量和方法。
6、不要从构造方法中直接传参数初始化静态数据域。最好使用静态的set方法改变静态数据域。
以及部分java程序设计的基本原则就比如:单一职责原则。
在上述Atm类设计中还对 lterator进行了一个基本了解
Iterator(迭代器)
java Iterator(迭代器)不是一个集合,它是一种用于访问集合的方法,可用于迭代 ArrayList 和 HashSet 等集合。
Iterator 是 Java 迭代器最简单的实现,ListIterator 是 Collection API 中的接口, 它扩展了 Iterator 接口
Java中的Iterator功能比较简单,并且只能单向移动:
(1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。
(2) 使用next()获得序列中的下一个元素。
(3) 使用hasNext()检查序列中是否还有元素。
(4) 使用remove()将迭代器新返回的元素删除。
Listlterator
而ListIterator是一个功能更加强大的, 它继承于Iterator接口,只能用于各种List类型的访问
相较于上面的迭代器,listlterator可以实现双向移动遍历,也可以实现增加或替换元素。