Banking系统
- 开发前的话:
- Banking系统是校验初级程序员对Java语言特性的最佳实践项目,该项目分成八个设计阶段,每个阶段都在考量码哥对Java语言特性的熟练度。每个阶段说明都十分详细,初学者一定要基于"每个阶段的说明"去一步步去实现,实现过程中做到不超纲,不放水。免得庞大的代码量把自己绕成一个傻Ber...待到完成任务,就可以根据最终的实现结果回溯自己的不足。(记住:即使把编程语言的特性倒背如流也无法成为真正的专家,成为专家前需要不断模仿,从模仿中提炼自己思考问题的方式)。
- 实现过程
- 第一阶段
- 您是否会创建一个简单的"银行程序包"?
- 您是否对Java语言中面向对象特性及构造器的创建和使用知之甚详?
- 第二阶段
- 您是否知道如何使用”引用类型的成员变量"?
- 您是如何思考类间的组合关系?
- 第三阶段
- 您是否会使用或定义带有返回值类型的方法?
- 第四阶段
- 您是否会使用数组,以及区别数组与集合?
- 第五阶段
- 您是否理解面向对象的三大特性:继承?多态?以及方法的重写?
- 第六阶段
- 第七阶段
- 第八阶段
- 第一阶段
- 项目总结
第一阶段:
实验题目 1:创建一个简单的银行程序包实验目的:Java 语言中面向对象的封装性及构造器的创建和使用。实验说明:在这个练习里,创建一个简单版本的 Account 类。将这个源文件放入 banking 程序包中。在创建单个帐户的默认程序包中,已编写了一个测试程序 TestBanking。这个测试程序初始化帐户余额,并可执行几种简单的事物处理。最后,该测试程 序显示该帐户的最终余额。提示:1.创建 banking 包2. 在 banking 包下创建 Account 类。该类必须实现上述 UML 框图中的模型。a. 声明一个私有对象属性:balance,这个属性保留了银行帐户的当前(或 即时)余额。b. 声明一个带有一个参数( init_balance ) 的公有构造器, 这个参数为 balance 属性赋值。c. 声明一个公有方法 geBalance,该方法用于获取经常余额。d. 声明一个公有方法 deposit,该方法向当前余额增加金额。e. 声明一个公有方法 withdraw 从当前余额中减去金额。3.打开TestBanking.java文件,按提示完成编写,并编译 TestBanking.java 文件。4. 运行 TestBanking 类。可以看到下列输出结果:Creating an account with a 500.00 balanceWithdraw 150.00Deposit 22.50Withdraw 47.62The account has a balance of 324.88
- entity
- Account.java
package entity;public class Account {/*** balance:当前账户余额*/private double balance;/*** */public Account() {balance = 0;}/*** * @param balance*/public Account(double balance) {this.balance = balance;}/*** bean*/public double getBalance() {return balance;}/*** */public double deposit(double amt) {if(amt>10000){System.out.println("存款额度不得大于1万");}else{System.out.println("存款成功" );return balance = balance + amt;}return balance;}/*** 取款事务说明:* 1.balance=0时,不允许取款* 2.balance!=0时* 2.1 amt>balance时,不允许取款* 2.2 amt<=balance时 ,返回取款后的余额* * @param amt* @return*/public double withdraw(double amt) {if (balance != 0) {if (amt > balance) {System.out.println("余额不足,取款失败");} else {System.out.println("取款成功");return balance = balance - amt;}} elseSystem.out.println("取款失败");return balance;} }
- Account.java
第二阶段:
阶段二:扩展银行项目,添加一个 Customer 类。Customer 类将包含一个 Account对象。实验目的:使用引用类型的成员变量提示:1. 在banking包下的创建Customer类。该类必须实现上面的UML图表中的模型。a. 声明三个私有对象属性:firstName、lastName 和 account。b. 声明一个公有构造器,这个构造器带有两个代表对象属性的参数(f 和 l)c. 声明两个公有存取器来访问该对象属性,方法 getFirstName 和 getLastName返回相应的属性。d. 声明 setAccount 方法来对 account 属性赋值。e. 声明 getAccount 方法以获取 account 属性。2. 在 exercise2 主目录里,编译运行这个 TestBanking 程序。应该看到如下输出结果:Creating the customer Jane Smith.Creating her account with a 500.00 balance. Withdraw 150.00Deposit 22.50 Withdraw 47.62 Customer [Smith, Jane] has a balance of 324.88
- entity
- Account.java
-
package entity;public class Account {/*** balance:当前账户余额*/private double balance;/*** */public Account() {balance = 0;}/*** * @param balance*/public Account(double balance) {this.balance = balance;}/*** bean*/public double getBalance() {return balance;}/*** */public double deposit(double amt) {if(amt>10000){System.out.println("存款额度不得大于1万");}else{System.out.println("存款成功" );return balance = balance + amt;}return balance;}/*** 取款事务说明:* 1.balance=0时,不允许取款* 2.balance!=0时* 2.1 amt>balance时,不允许取款* 2.2 amt<=balance时 ,返回取款后的余额* * @param amt* @return*/public double withdraw(double amt) {if (balance != 0) {if (amt > balance) {System.out.println("余额不足,取款失败");} else {System.out.println("取款成功");return balance = balance - amt;}} elseSystem.out.println("取款失败");return balance;} }
- Customer.java
package entity;public class Customer {/*** 客户属性*/private Account account; // private String firstName;private String lastName;/*** */public Customer(String firstName, String lastName) {this.firstName = firstName;this.lastName = lastName;}public Customer() {// TODO Auto-generated constructor stub }public String getFirstName(){return firstName;}public String getLastName(){return lastName;}public Account getAccount(){return new Account();}public void setAccount(Account account){this.account=account;}@Overridepublic String toString(){return firstName+" | "+lastName;}}
第三阶段:
实验题目 3:修改 withdraw 方法以返回一个布尔值,指示交易是否成功。实验目的:使用有返回值的方法。:修改 Account 类:修改 deposit 方法返回 true(意味所有存款是成功的)。:修改 withdraw 方法来检查提款数目是否大于余额。如果 amt 小于 balance, 则从余额中扣除提款数目并返回 true,否则余额不变返回false。: 测试Creating the customer Jane Smith.Creating her account with a 500.00 balance.Withdraw 150.00: trueDeposit 22.50: trueWithdraw 47.62: trueWithdraw 400.00: falseCustomer [Smith, Jane] has a balance of 324.88
- entity
- Account.java
-
package entity; /*** 第三阶段修改处:”*“基于上阶段修改处的标记* @author doublezi**/ public class Account {/*** balance:当前账户余额*/private double balance;/*** */public Account() {balance = 0;}/*** * @param balance*/public Account(double balance) {this.balance = balance;}/*** bean*/public double getBalance() {return balance;}//*public boolean deposit(double amt) {if(amt>10000){System.out.println("存款额度不得大于1万");}else{balance=balance+amt;System.out.println("存款成功" );return true;//* }return false;//* }/*** 取款事务说明:(第三阶段)* getBalance():当前账户余额* 1. getBalance()>amt : false* 2. 反之: 更新账户余额* * * @param amt* @return*///*public boolean withdraw(double amt) {if(getBalance()<amt){return false;//*}else{balance=balance-amt;System.out.println("取款成功");return true;//* }} }
- Customer.java
-
package entity;public class Customer {/*** 客户属性*/private Account account; // private String firstName;private String lastName;/*** */public Customer(String firstName, String lastName) {this.firstName = firstName;this.lastName = lastName;}public Customer() {// TODO Auto-generated constructor stub }public String getFirstName(){return firstName;}public String getLastName(){return lastName;}public Account getAccount(){return new Account();}public void setAccount(Account account){this.account=account;}@Overridepublic String toString(){return firstName+" | "+lastName;}}
第四阶段:
第四阶段说明
实验题目 4:将用数组实现银行与客户间的多重关系。实验目的:在类中使用数组作为模拟集合操作。对银行来说,可添加 Bank 类。 Bank 对象跟踪自身与其客户间的关系。用 Customer 对象的数组实现这个集合化的关系。还要保持一个整数属性来跟踪银 行当前有多少客户。a. 创建 Bank 类b. 为 Bank 类 增 加 两 个 属 性 : customers(Customer对象的数组 ) 和numberOfCustomers(整数,跟踪下一个 customers 数组索引)c. 添加公有构造器,以合适的最大尺寸(至少大于 5)初始化 customers 数组。d. 添加 addCustomer 方法。该方法必须依照参数(姓,名)构造一个新的Customer对象然后把它放到 customer 数组中。还必须把 numberofCustomers属性的值加 1。e. 添加 getNumOfCustomers 访问方法,它返回 numberofCustomers 属性值。f. 添加 getCustomer方法。它返回与给出的index参数相关的客户。g. 编译并运行 TestBanking 程序。可以看到下列输出结果:Customer [1] is Simms,Jane Customer [2] is Bryant,Owen Customer [3] is Soley,Tim Customer [4] is Soley,Maria
- entity
- Account.java
-
package entity; /*** 第三阶段修改处:** @author doublezi**/ public class Account {/*** balance:当前账户余额*/private double balance;/*** */public Account() {balance = 0;}/*** * @param balance*/public Account(double balance) {this.balance = balance;}/*** bean*/public double getBalance() {return balance;}//*public boolean deposit(double amt) {if(amt>10000){System.out.println("存款额度不得大于1万");}else{balance=balance+amt;System.out.println("存款成功" );return true;//* }return false;//* }/*** 取款事务说明:(第三阶段)* getBalance():当前账户余额* 1. getBalance()>amt : false* 2. 反之: 更新账户余额* * * @param amt* @return*///*public boolean withdraw(double amt) {if(getBalance()<amt){return false;//*}else{balance=balance-amt;System.out.println("取款成功");return true;//* }} }
- Customer.java
-
package entity;public class Customer {/*** 客户属性*/private Account account; // private String firstName;private String lastName;/*** */public Customer(String firstName, String lastName) {this.firstName = firstName;this.lastName = lastName;}public Customer() {// TODO Auto-generated constructor stub }public String getFirstName(){return firstName;}public String getLastName(){return lastName;}public Account getAccount(){return new Account();}public void setAccount(Account account){this.account=account;}@Overridepublic String toString(){return firstName+" | "+lastName;}}
- Bank.java
-
package entity;public class Bank {private Customer customers[];private int noOfCustomers[];public static int count = 0;public static int index = 0;public Bank() {customers = new Customer[5];noOfCustomers = new int[5];}public void addCustomer(String firstName, String lastName) {index = +count; // 区别:对于计数器和索引器,使用静态变量和局部变量的区别customers[index] = new Customer(firstName, lastName);noOfCustomers[index] = (++count);}public int getNoOfCustomers() {return noOfCustomers.length;}public int getNoCustomers(int index) {return noOfCustomers[index];}public Customer getCustomer(int index) {return customers[index];} }
第五阶段:
实验题目 5: 在银行项目中创建 Account 的两个子类:SavingAccount 和 CheckingAccount实验目的:继承、多态、方法的重写。提 示: 创建 Account 类的两个子类:SavingAccount 和 CheckingAccount 子类a. 修改 Account 类;将 balance 属性的访问方式改为 protectedb. 创建 SavingAccount 类,该类继承 Account 类c. 该类必须包含一个类型为 double 的 interestRate 属性d. 该类必须包括带有两个参数(balance 和 interest_rate)的公有构造器。该构造器必须通过调用 super(balance)将 balance 参数传递给父类构造器。实现 CheckingAccount 类1. CheckingAccount 类必须扩展 Account 类2. 该类必须包含一个类型为 double 的 overdraftProtection 属性。3. 该类必须包含一个带有参数(balance)的共有构造器。该构造器必须通过调用 super(balance)将 balance 参数传递给父类构造器。4. 给类必须包括另一个带有两个参数(balance 和 protect)的公有构造器。该构造器必须通过调用 super(balance)并设置 overdragtProtection 属性,将 balance 参数传递给父类构造器。5. CheckingAccount 类必须覆盖 withdraw 方法。此方法必须执行下列检查。如 果当前余额足够弥补取款 amount,则正常进行。如果不够弥补但是存在透支 保护,则尝试用 overdraftProtection 得值来弥补该差值(balance-amount). 如果弥补该透支所需要的金额大于当前的保护级别。则整个交易失败,但余 额未受影响。6. 在主 exercise1 目录中,编译并执行 TestBanking 程序。输出应为: Creating the customer Jane Smith. Creating her Savings Account with a 500.00 balance and 3% interest.
- entity
- Account.java
-
package entity; /*** 第三阶段修改处:flag=** @author doublezi**/ public class Account {/*** balance:当前账户余额*/protected double balance;/*** */public Account() {balance = 0;}/*** * @param balance*/public Account(double balance) {this.balance = balance;}/*** bean*/public double getBalance() {return balance;}/*** *///*public boolean deposit(double amt) {if(amt>10000){System.out.println("存款额度不得大于1万");}else{balance=balance+amt;System.out.println("存款成功" );return true;//* }return false;//* }/*** 取款事务说明:(第三阶段)* getBalance():当前账户余额* 1. getBalance()>amt : false* 2. 反之: 更新账户余额* * * @param amt* @return*///*public boolean withdraw(double amt) {if(getBalance()<amt){return false;//*}else{balance=balance-amt;System.out.println("取款成功");return true;//* }} }
- Bank.java
-
package entity;public class Bank {private Customer customers[];private int noOfCustomers[];public static int count = 0;public static int index = 0;public Bank() {customers = new Customer[5];noOfCustomers = new int[5];}public void addCustomer(String firstName, String lastName) {index = +count; // 区别:对于计数器和索引器,使用静态变量和局部变量的区别customers[index] = new Customer(firstName, lastName);noOfCustomers[index] = (++count);}public int getNoOfCustomers() {return noOfCustomers.length;}public int getNoCustomers(int index) {return noOfCustomers[index];}public Customer getCustomer(int index) {return customers[index];} }
- Customer
-
package entity;public class Customer {/*** 客户属性*/private Account account; // private String firstName;private String lastName;/*** */public Customer(String firstName, String lastName) {this.firstName = firstName;this.lastName = lastName;}public Customer() {// TODO Auto-generated constructor stub }public String getFirstName(){return firstName;}public String getLastName(){return lastName;}public Account getAccount(){return new Account();}public void setAccount(Account account){this.account=account;}@Overridepublic String toString(){return firstName+" | "+lastName;}}
- CheckingAccount.java(extends Account)
-
package entity;import java.util.Scanner;/*** Checking Account:普通支票账户-->无息 特点:可以免费多次存取现金,无利息* * @author doublezi**/ public class CheckingAccount extends Account {/*** 透支额度*/private double overDraftProtection;public double getOverDraftProtection() {if (balance >= 0 && balance <= 1000) {return overDraftProtection = 100;}if (balance > 1000 && balance <= 5000) {return overDraftProtection = 500;}if (balance > 5000 && balance <= 10000) {return overDraftProtection = 700;}return -1;}/*** */public CheckingAccount() {balance = Math.random() * 10000;}public CheckingAccount(double balance) {this.balance = balance;}public CheckingAccount(double balance, double overDraftProtection) {super(balance);this.overDraftProtection = overDraftProtection;}@Overridepublic double getBalance() {return balance;}@Overridepublic boolean withdraw(double amt) {if (balance-amt>0) {balance = balance - amt;System.out.println("余额:" + balance);return true;} else {// 获取可透支额度if(amt==balance+getOverDraftProtection()){System.out.println("Checking Account:"+(balance-amt));}else// 获取透支后余额System.out.println("请在可透支范围内提款!");return true;}}@Overridepublic String toString() {return "Checking Account:" + balance + "$ , 可透支额度为:" + this.getOverDraftProtection()+ "$";} }
- SavingAccount.java(extends Account)
-
package entity;/*** Saving Account:活期储蓄账户-->有固定利率 特点:存放在Saving Account的钱,通常一个月可以有有限次数提款* 假定每月限制仅能提款一次,超过提款次数限制,则收取手续费(30¥)* * @author doublezi**/ public class SavingAccount extends Account {/*** 利率: interest Rate*/private double interestRate;public SavingAccount() {}public SavingAccount(double balance, double interestRate) {super(balance);this.balance = balance;}/*** * @param a* @param amt* @return*/public double saveTactics(Account a, double amt) {return 0;}@Overridepublic String toString() {return "Saving Account:" + balance + "¥";} }
第五阶段扩展:
创建客户账户: 说明---实际生活中,我们所有持有某个特定银行中的多张银行卡,具体卡有没有钱那hi另一回事了。所以当设计一个客户拥有多个账户时,是合乎情理的,符合实际情况 实验目的:instanceof 运算符的应用提 示:修改 Customer 类1. 修改 Customer 类来处理具有多种类型的联合账户。(例如用数组表示多重性一节所作的,该类必须包括以下的公有方法:addAccount(Account),getAccount(int)和 getNumOfAccounts()。每个 Customer 可以有多个 Account。(声明至少有 5 个)2. 完成 TestBanking 程序该程序创建一个客户和账户的集合,并生成这些客户及其账户余额的报告。在TestBanking.Java 文件中,你会发现注释块以/***…***/来开头和结尾。这些注释只是必须提供的代码的位置。3. 使用 instanceof 操作符测试拥有的账户类型,并且将 account_type 设置为适当的值,例如:“SavingsAccount”或“CheckingAccount”。4. 编译并运行该程序,将看到下列结果----------------------------------------------- 客户:客户名 持卡类型:定期储蓄账户,账户余额: ***¥ 持卡类型:活期储蓄账户,账户余额: ***¥ ------------------------------------------------ 注:关于"Checking Account"和"Saving Account"的区别: 一般“个人”在国外银行开设账户,依性质不同主要分为下列几种: 1)普通支票账户(Checking Account);一般无息 2)活期储蓄账户(Savings Account);一般固定利率 3)定期储蓄账户(Certificate of Deposit 简称 CD);固定利率 4)浮动利率账户(Money Market Account);也算活期储蓄账户的一种,但利率随行就市每日调整一个是经常账户 checking account 根据所选的package 可以免费多次存取提取现金。 没有利息。 一个是储蓄账户 saving account。这个账户是有利息的。 但是这个一般钱放进去一个月只有有限的次数可以动,一般一个月一次,超过次数若要提取的话,根据账户种类会收不同额度的手续费,例如两块,或者五块。 CUSTOMERS REPORT================Customer: Simms, JaneSavings Account: current balance is ¥500.00Checking Account: current balance is ¥200.00Customer: Bryant, OwenChecking Account: current balance is ¥200.00Customer: Soley, TimSavings Account: current balance is ¥1,500.00Checking Account: current balance is ¥200.00Customer: Soley, MariaChecking Account: current balance is ¥200.00Savings Account: current balance is ¥150.00
- entity
- Account.java
package entity; /*** 第三阶段修改处:flag=** @author doublezi**/ public class Account {/*** balance:当前账户余额*/protected double balance;/*** */public Account() {balance = 0;}/*** * @param balance*/public Account(double balance) {this.balance = balance;}/*** bean*/public double getBalance() {return balance;}@Overridepublic String toString(){return "账户余额:"+balance;}/*** *///*public boolean deposit(double amt) {if(amt>10000){System.out.println("存款额度不得大于1万");}else{balance=balance+amt;System.out.println("存款成功" );return true;//* }return false;//* }/*** 取款事务说明:(第三阶段)* getBalance():当前账户余额* 1. getBalance()>amt : false* 2. 反之: 更新账户余额* * * @param amt* @return*///*public boolean withdraw(double amt) {if(getBalance()<amt){return false;//*}else{balance=balance-amt;System.out.println("取款成功");return true;//* }} }
- Bank.java
package entity;public class Bank {private Customer customers[];private int noOfCustomers[];public static int count = 0;public static int index = 0;public Bank() {customers = new Customer[5];noOfCustomers = new int[5];}public void addCustomer(String firstName, String lastName) {index = +count; // 区别:对于计数器和索引器,使用静态变量和局部变量的区别customers[index] = new Customer(firstName, lastName);noOfCustomers[index] = (++count);}public int getNoOfCustomers() {return noOfCustomers.length;}public int getNoCustomers(int index) {return noOfCustomers[index];}public Customer getCustomer(int index) {return customers[index];} }
- CheckingAccount.java(extends Account)
package entity;import java.util.Scanner;/*** Checking Account:普通支票账户-->无息 特点:可以免费多次存取现金,无利息* * @author doublezi**/ public class CheckingAccount extends Account {/*** 透支额度*/private double overDraftProtection;public double getOverDraftProtection() {if (balance >= 0 && balance <= 1000) {return overDraftProtection = 100;}if (balance > 1000 && balance <= 5000) {return overDraftProtection = 500;}if (balance > 5000 && balance <= 10000) {return overDraftProtection = 700;}return -1;}/*** */public CheckingAccount() {balance = Math.random() * 10000;}public CheckingAccount(double balance) {this.balance = balance;}public CheckingAccount(double balance, double overDraftProtection) {super(balance);this.overDraftProtection = overDraftProtection;}@Overridepublic double getBalance() {return balance;}@Overridepublic boolean withdraw(double amt) {if (balance-amt>0) {balance = balance - amt;System.out.println("余额:" + balance);return true;} else {// 获取可透支额度if(amt==balance+getOverDraftProtection()){System.out.println("Checking Account:"+(balance-amt));}else// 获取透支后余额System.out.println("请在可透支范围内提款!");return true;}}@Overridepublic String toString() {return "Checking Account:" + balance + "$ , 可透支额度为:" + this.getOverDraftProtection()+ "$";} }
- SavingAccount.java(extends Account)
package entity;/*** Saving Account:活期储蓄账户-->有固定利率 特点:存放在Saving Account的钱,通常一个月可以有有限次数提款* 假定每月限制仅能提款一次,超过提款次数限制,则收取手续费(30¥)* * @author doublezi**/ public class SavingAccount extends Account {/*** 利率: interest Rate*/private double interestRate;public SavingAccount() {balance = Math.random() * 10000;}public SavingAccount(double balance, double interestRate) {super(balance);this.balance = balance;}/*** * @param a* @param amt* @return*/public double saveTactics(Account a, double amt) {return 0;}@Overridepublic String toString() {return "Saving Account:" + balance + "¥";} }
- CheckingAccount.java(extends Account)
- Costomer.java
package entity;public class Customer {/*** 客户属性*/private Account account; // private String firstName;private String lastName;private Account accounts[];private int noOfAccounts[];public static int count = 0; //模拟账户编号(1,2,3,4,5)public static int index = 0; //模拟数组索引值(0,1,2,3,4)/*** */public Customer(String firstName, String lastName) {this.firstName = firstName;this.lastName = lastName;accounts = new Account[5];noOfAccounts = new int[5];}public Customer() {accounts = new Account[5];noOfAccounts = new int[5];}public String getFirstName() {return firstName;}public String getLastName() {return lastName;}public Account getAccount() {return new Account();}public void setAccount(Account account) {this.account = account;}@Overridepublic String toString() {return firstName + " | " + lastName;}/*** 客户类自己的行为方法 1.通常一个客户可以拥有多个银行账户*/public Account addAccount(Account a) {// 索引设计的准确性 index = +count;if (index % 2 == 0) {a = new CheckingAccount();} else {a=new SavingAccount();}accounts[index] = a;noOfAccounts[index] = (++count);return a;}public int getNoOfAccounts(int index) {return noOfAccounts[index];}/*** 指定的索引存放着客户(Customer)不同的账户(Account)* * @param index* @return*/public Account getAccounts(int index) {return accounts[index];}}
- Account.java