Java实现银行ATM系统

用Java模拟一个银行ATM系统,供大家参考,具体内容如下

系统功能介绍:

使用面向对象的编程思想,尽可能模拟真实世界中的银行ATM业务流程。
main方法里通过调用一行代码,完成整个业务流程的顺序调用。
加入了身份证号,手机号等元素,虽然他们不涉及银行卡的业务处理,但它们是真实世界中办理银行卡的必需条件,这些在代码中也有所体现。
为了尽可能使得随机生成的身份证号码和手机号码和银行卡号切合实际,还手动设计了一个工具类,用来生成随机的号码。
其中涉及到的知识,包括但不限于static修饰符的使用,集合的使用,权限修饰符的控制,类与类之间关系的设计,类构建的属性初始化控制,Scanner输入控制,工具类BigDecimal和DecimalFormat的使用,随机数的生成等。
但其实最难的还是设计,类与类之间关系的设计,类的属性和方法的设计,它们都至关重要,它们可以说是面向对象编程的核心。一旦属性或方法设计得不合理,程序即使可以运行,但它的开发过程必然是违背人的正常思维的,也会使得后期的更改和维护变得异常棘手。
编写这个程序相对来讲还是很有挑战性的,虽然用到的知识不多,但也很考究你的设计能力和思维能力。

全部代码

银行系统类BankSystem:

public class BankSystem {
 private static ATM_Machine atm = new ATM_Machine();
 private static Set<BankCard> allBankCard = new HashSet<>();

 public static void addBanCard(BankCard card){
  allBankCard.add(card);
 }
 public static Set getAllBanCard(){
  return allBankCard;
 }

 public static boolean loginATM(ATM_Machine atm){
  Scanner input = new Scanner(System.in);
  String cardNum;
  System.out.println("请输入您的银行卡号:(误操作,按#号键敲回车可再次回到系统主页面)");
  cardNum = input.nextLine();
  if (cardNum.equals("#")){
   start();
  }
  ArrayList<BankCard> allBankCard = new ArrayList<>(BankSystem.getAllBanCard());

  BankCard card = null;
  boolean isExist = false;
  for (int i = 0;i<allBankCard.size();i++){
   if(allBankCard.get(i).getCARDNUM().equals(cardNum)){
    card = allBankCard.get(i);//卡号存在,实例化该银行卡
    isExist = true;
   }
  }
  if (isExist == false){
   System.err.println("您输入的银行卡号不存在,请重新输入");
   loginATM(atm);//递归调用
  }
  String name = card.getHolder().getName();
  System.out.println("欢迎"+name+"使用本公司智能提示ATM系统\n请输入您的银行卡密码:");
  int password = input.nextInt();
  int n = 3;//3次输入密码的机会
  while (n>0) {
   if (!atm.loginCheck(card,password)) {
    n--;
    System.err.println("您输入的密码错入,请重新输入,您还有" + n + "次输入机会!");
    if(n==0){
     atm.exit();
     return false;
    }
    password = input.nextInt();
   }else{
    System.out.println("密码正确,正在启动系统···");
    try {
     Thread.sleep(3000);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    atm.showOperation(card);
    return true;
   }
  }
  atm.exit();
  return false;
 }
 public static void start(){
  System.out.println("\t=============欢迎进入我们的银行系统=============\t");
  System.out.println("1.没有银行卡,我要办理\t\t\t2.已有银行卡,我要通过ATM办理一些业务");
  System.out.println("3.退出整个银行系统");
  System.out.println("请选择您的操作:");
  Scanner input = new Scanner(System.in);
  //只需要输入名字,即可办理银行卡。身份证号,手机号,银行卡号,自动随机生成(只是为了最大限度模拟现实情景的同时,又不让测试时输入太多繁琐的东西)
  String option = input.nextLine();
  if (option.equals("1")){
   Customer customer = new Customer();
   customer.registerIdentify();
   BankCard card = customer.applyBankCard(customer.getIdentityCard(), customer.getPhoneNum());
   //allBankCard.add(card);//将新办理的银行卡存入系统中
   //办理完银行卡会在applyBankCard方法内自动存入系统中
   System.out.println("您的银行卡已经办理完毕,即将再次进入系统···");
   try {
    Thread.sleep(2000);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   start();
  }else if(option.equals("2")){
   loginATM(atm);
  }else if (option.equals("3")){
   System.out.println("您慢走,感谢你的到来,欢迎下次再来办理业务");
  }else {
   System.err.println("您输入了不合法的字符");
   start();
  }
 }
}

ATM_Machine类:

public class ATM_Machine {
 private boolean isFirstShow = true;
 public boolean loginCheck(BankCard card,int password){
  int truePassword = card.getPassword();
  if (truePassword == password){
   return true;
  }
  return false;
 }
 public void showTitle(){
  System.out.println("------------ATM系统------------");
 }
 //登录成功后,系统开始工作
 public void showOperation(BankCard card){
  //登录,查询余额,存款,取款,转账,销户,开户,退出
  Scanner input = new Scanner(System.in);
  if(isFirstShow) {
   this.showTitle();
   isFirstShow = false;
  }
  System.out.println("1.查询余额\t\t\t2.存款");
  System.out.println("3.转账 \t\t\t4.取款");
  System.out.println("5.销户 \t\t\t6.退出");
  System.out.println("请输入您要进行的操作:");
  int option = input.nextInt();
  input.nextLine();
  switch (option){
   case 6:exit();
    BankSystem.start();
    break;
   case 1:showBalance(card);
    break;
   case 2:showDeposit(card);
    break;
   case 3:showTransfer(card);
    break;
   case 4:showWithdrawal(card);
    break;
   case 5:closeAccount(card);
    break;
   default:
    System.err.println("您输入了不合法字符,建议您重新输入!");
    showOperation(card);//递归调用
  }
 }
 //退出系统,密码输入错误3次,或者交易完成后,应该退出系统
 public void exit(){
  System.out.println("ATM系统关闭");
 }

 public static void main(String[] args) {
  ATM_Machine a = new ATM_Machine();

 }
 public BigDecimal queryBalance(BankCard card){
  return card.getBalance();
 }
 public void showBalance(BankCard card){
  this.showTitle();
  System.out.println("您的余额为:"+queryBalance(card));
  this.showOperation(card);
 }
 //deposit存款
 public void deposit(BankCard card,int amount){
  card.setBalance(card.getBalance().add(new BigDecimal(amount)));
 }
 public void showDeposit(BankCard card){
  this.showTitle();
  int amount = checkAmountInput("存款",20000);//一次最多存2万
  deposit(card,amount);//执行存款操作
  System.out.println("存款成功,您当前卡内余额为:"+card.getBalance());
  showOperation(card);
 }
 //取款:withdrawal
 public void withdrawal(BankCard card,int amount){
  card.setBalance(card.getBalance().subtract(new BigDecimal(amount)));
 }
 public void showWithdrawal(BankCard card){
  this.showTitle();
  int amount = checkAmountInput("取款",3000);//一次最多存2万
  withdrawal(card,amount);//执行存款操作
  System.out.println("取款成功,您当前卡内余额为:"+card.getBalance());
  showOperation(card);
 }
 //销户:closing an account
 public void closeAccount(BankCard card ){
  Scanner input = new Scanner(System.in);
  System.err.println("销户是一个危险操作,你的所有余额将被清空,卡号将会回收,您确定要继续吗?");
  System.out.println("1.是的,继续\t2.取消该操作");
  String s = input.nextLine();
  if (s.equals("1")){
   BankSystem.getAllBanCard().remove(card);
   card = null;
   System.out.println("您已经成功销户");
   exit();
   BankSystem.start();
  }else if (s.equals("2")){
   showOperation(card);
  }else{
   System.err.println("您输入了不合法字符!!!\n麻烦您重复确认您的操作:");
   closeAccount(card);//递归调用
  }
 }

 //转账:transfer
 public void transfer(BankCard myCard,BankCard anotherCard,int amount){
  myCard.setBalance(myCard.getBalance().subtract(new BigDecimal(amount)));
  anotherCard.setBalance(anotherCard.getBalance().add(new BigDecimal(amount)));
 }
 public void showTransfer(BankCard myCard){
  Scanner input = new Scanner(System.in);
  System.out.println("请输入对方的银行卡号:");
  String cardNum = input.nextLine();
  ArrayList<BankCard> allBankCard = new ArrayList<>(BankSystem.getAllBanCard());
  BankCard anotherCard = null;
  boolean isExist = false;
  for (int i = 0;i<allBankCard.size();i++){
   if(allBankCard.get(i).getCARDNUM().equals(cardNum)){
    anotherCard = allBankCard.get(i);//卡号存在,实例化该银行卡
    isExist = true;
    break;
   }
  }
  if (isExist == false){
   System.err.println("您输入的银行卡号不存在,请重新输入");
   showTransfer(myCard);//递归调用
  }
  int amount = checkAmountInput("转账",5000);//转账每次只能转5000
  if (myCard.getBalance().compareTo(new BigDecimal(amount)) == -1){
   System.err.println("对不起,您的余额不足");
   System.out.println();
   showOperation(myCard);
  }
  transfer(myCard,anotherCard,amount);
  System.out.println("转账成功!请继续您的操作");
  showOperation(myCard);
 }
 //====================================
 private int checkAmountInput(String operation,int maxAmount){
  Scanner input = new Scanner(System.in);
  int amount;
  System.out.println("请输入您要"+operation+"的金额(一次不得超过"+maxAmount+"):");
  while (true) {
   try {
    amount = input.nextInt();
    input.nextLine();
    if (amount % 100 != 0) {
     System.err.println(operation+"数目必须是100的整数倍,请重新输入:");
     continue;
    }
    if (amount > maxAmount) {
     System.err.println(operation+"数目一次不得超过"+maxAmount+",请重新输入:");
     continue;
    }
    break;
   } catch (InputMismatchException e) {
    input.nextLine();//当用户输入的类型不匹配,清空输入栈
    System.err.println(operation+"数额必须是整数,请重新输入:");
   }
  }
  return amount;
 }
 //===================================================
}

银行卡BankCard类:

public class BankCard {
 /*对于static关键字的理解:如果某一个属性,设置了static修饰符,就意味着,不管创建多少个对象,该属性却只有一份,被所有对象所共享
 一旦某一个对象修改了这个属性,其他对象的这个属性都会改变,因为这个属性是公共的。
 所以: 千万要注意:static修饰符不可以滥用!!
  */
 private BigDecimal balance = new BigDecimal("0");//余额
 private String CARDNUM;//卡号,一般是19位的,纯数字的
 private Customer holder;//持有者
 private int password;//密码

 public static boolean checkIsExistThisBankCardNum(String bankCardNum){
  boolean flag = false;
  ArrayList<BankCard> allBanCard = new ArrayList<>(BankSystem.getAllBanCard());
  for (int i = 0;i<allBanCard.size();i++){
   while (allBanCard.get(i).getCARDNUM().equals(bankCardNum)){
    flag = true;//存在这个银行卡号了,需要重新生成,虽然概率很低。
   }
  }
  return flag;
 }

 public BankCard(String IDNum,String phoneNum,int password){
  //需要一个身份证号,和一个手机号码
  this.holder = IdentityManageSystem.getIdentifyMsg().get(IDNum);
  String cardNum = new GenerateRandomString().generateIntString(19);//19位随机数字
  while (checkIsExistThisBankCardNum(cardNum)){
   //存在这个银行卡号了,需要重新生成,虽然概率很低。
   cardNum = new GenerateRandomString().generateIntString(19);//19位随机数字
  }
  this.CARDNUM = cardNum;
  this.password = password;
  //设置开户随机金额(模拟一下)
  Double money = new Random().nextDouble()*100+1;
  DecimalFormat df = new DecimalFormat("#.00");
  String bd = df.format(money);
  this.balance = new BigDecimal(bd);
 }
 public boolean equals(Object obj){
  if (this==obj){
   return true;
  }
  if (obj instanceof BankCard){
   BankCard newCard = (BankCard)obj;
   if (newCard.getCARDNUM().equals(this.CARDNUM))
    //只要卡号相同,就认为是同一张银行卡
    return true;
  }
  return false;
 }
 public int hashCode(){
  return this.CARDNUM.hashCode();
 }

 public BigDecimal getBalance() {
  return balance;
 }

 public String getCARDNUM() {
  return CARDNUM;
 }

 public Customer getHolder() {
  return holder;
 }

 public void setBalance(BigDecimal balance) {
  this.balance = balance;
 }

 public void setPassword(int password) {
  this.password = password;
 }

 public int getPassword() {
  return password;
 }
}

顾客Customer类:

public class Customer {
 private IdentityCard identityCard;//身份证
 private String phoneNum;//手机号
 private String name;//客户的姓名
 private int age;//年龄

 {
  GenerateRandomString g = new GenerateRandomString();
  phoneNum = "1"+ g.generateIntString(10);//第一个数是1,后面10位随机的电话号码
 }

 public Customer(){
  Scanner input = new Scanner(System.in);
  System.out.println("您好,请问您叫什么名字?:");
  String name = input.nextLine();
  this.name = name;
 }
 public Customer(String IDNum){

  //判断身份证号对不对,不是在这里判断!
 }
 //注册身份证
 public IdentityCard registerIdentify(){
  if (this.getName()!=null){
   IdentityCard card = new IdentityCard(this);
   this.identityCard = card;
   IdentityManageSystem.getIdentifyMsg().put(card.getIDNum(),this);//注册完身份证,把键值对身份证号-姓名放入身份管理系统
   return this.identityCard;
  }
  System.err.println("您还没有名字呢");
  return null;
 }
 public BankCard applyBankCard(IdentityCard card,String phoneNum){
  Scanner input = new Scanner(System.in);

  System.out.println("顾客"+this.getName()+"身份证号:"+this.getIdentityCard().getIDNum()+
    "电话号码:"+this.getPhoneNum()+"\n正在申请银行卡···\n请设置您的银行卡密码(规则:密码必须是6位纯数字):");
  int password;
  while (true) {
   try {
    password = input.nextInt();
    break;
   } catch (InputMismatchException e) {
    input.nextLine();//把多余的回车读取走
    System.err.println("您输入的密码不合法,请重新输入:");
   }
  }
  String pswStr = String.valueOf(password);
  while (pswStr.length()!=6) {
   System.err.println("您输入的密码长度不是6位,请重新输入:");
   password = input.nextInt();
   pswStr = String.valueOf(password);
  }

  //需要一个身份证(而不是号码),和一个手机号码
  BankCard bankCard = new BankCard(card.getIDNum(), phoneNum,password);
//  BankSystem.getAllBanCard().add(bankCard);//办理完后自动添加到系统库中
  BankSystem.addBanCard(bankCard);
  System.out.println("银行卡办理完毕,您的卡号是:"+bankCard.getCARDNUM()+"\n请妥善保管您的银行卡,牢记密码!!!");
  return bankCard;
 }

 public IdentityCard getIdentityCard() {
  if(this.identityCard==null){
   System.err.println("您还没有注册身份证,赶快申领一个吧!");
  }
  return identityCard;
 }

 public String getPhoneNum() {
  return phoneNum;
 }

 public String getName() {
  return name;
 }
}

身份证类IdentityCard:

/**
 * 这个类用来描述身份证
 */
public class IdentityCard {
 private String IDNum;//身份证号,一般是18位的,最后一位可以是字母
 private Customer holder;//持有者

 public IdentityCard(Customer holder) {
  //构建一个身份证,必须有持有者才行
  //身份证号,我帮你随机生成
  GenerateRandomString g = new GenerateRandomString();
  this.IDNum = g.generateIDNum();
  this.holder = holder;
 }

 public String getIDNum() {
  return IDNum;
 }

 public Customer getHolder() {
  return holder;
 }
}

身份管理系统类IdentityManageSystem :

public class IdentityManageSystem {
 private static Map<String,Customer> identityMsg = new HashMap<>();
 public static Map<String,Customer> getIdentifyMsg(){
  return identityMsg;
 }
}

自设计的工具类GenerateRandomString:

public class GenerateRandomString {
 private char[] str = "qwertyuiopasdfghjklzxcvbnm147258369".toCharArray();
 private String[] head = new String []{"140829","142732"};//两种常见的身份证号头部

 public String generateIntString(int length){
  StringBuilder intString = new StringBuilder();
  for (int i = 0;i<length;i++){
   intString.append(new Random().nextInt(10));
  }
  return intString.toString();
 }
 public String generateIDNum(){
  String idHead = head[new Random().nextInt(2)];//身份证号头部
  String year = String.valueOf((int)(Math.random()*121)+1900);//1900--2020,1900到2021但不包括2021
  String month = String.valueOf((int)(Math.random()*12)+1);//1到13但不包括13
  month = this.complement(month);
  String day = String.valueOf((int)(Math.random()*30)+1);//1到31但不包括31
  day = this.complement(day);
  String randomstr = generateIntString(3);//身份证的后4位的前3位随机数字
  String last = String.valueOf(str[new Random().nextInt(str.length)]);//身份证的最后一位,随机字母或数字
  StringBuilder builder = new StringBuilder();
  builder.append(idHead).append(year).append(month).append(day).append(randomstr).append(last);
  return builder.toString();
 }
 private String complement(String monthOrDay){
  //补全月份或日期,如果字符串长度小于2,就往前面加个0补全
  if (monthOrDay.length()==1){
   String result = "0".concat(monthOrDay);
   return result;
  }
  return monthOrDay;
 }
}

测试类:

public class MyTest {
 public static void main(String[] args) {
  BankSystem.start();
 }
}

示例截图

更多学习资料请关注专题《管理系统开发》。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 使用java实现银行家算法

    银行家算法核心 先寻找满足系统当前剩余的资源量(avaliable )>=进程运行所需的资源数的进程(need),再假设这个进程安全校验是成功的,当这个进程运行完毕后,释放资源后,现在系统当前剩余的资源(avaliable)=avaliable+该线程之前已分配的资源(allocation) ,将该节点进程设为处理时忽略进程,再以上条件为前提进行安全校验. 安全校验:一个进程获得资源后,运行完毕,释放之前分配的资源,其他的线程可以继续运行,而不会造成死锁. 这样就会产生回溯. 满足条件:是否存在

  • java实现简单银行家算法

    本文实例为大家分享了java实现银行家算法的具体代码,供大家参考,具体内容如下 题目: 初始时,Allocate[i,j]=0,表示初始时没有进程得到任何资源.假定进程对资源的请求序 列为: Request(1)[M]=(1,0,0); Request(2)[M]=(2,1,0); Request(2)[M]=(2,0,1); Request(3)[M]=(2,1,1); Request(4)[M]=(0,0,2); Request(2)[M]=(1,0,1); Request(1)[M]=(1

  • java代码实现银行管理系统

    本文实例为大家分享了java银行管理系统的具体代码,供大家参考,具体内容如下 银行业务调度 一.系统要求 1.银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口. 2.有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费.电话费之类业务的客户). 3.异步随机生成各种类型的客户,生成各类型用户的概率比例为: VIP客户 :普通客户 :快速客户  =  1 :6 :3. 4.客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客

  • java实现银行管理系统

    本文实例为大家分享了java实现银行管理系统的具体代码,供大家参考,具体内容如下 Bank类 package First; import java.util.TreeSet; //银行类 public class Bank { private String Bankname = "坑对对银行"; //银行名称 TreeSet<User> holder = null; //银行存储的信息 private static Bank INSTANCE = new Bank(); p

  • java实现银行家算法(Swing界面)

    java代码实现了银行家算法,界面写的个人认为还是较为细致的,完整的实现了找安全序列等算法功能,可作为参考学习银行家算法. 直接上代码:①界面展示方法: public void ShowFrame() { this.setSize(500, 350); //大小 this.setAlwaysOnTop(true); this.setResizable(false);//不可拖动 this.setLayout(new BorderLayout()); this.setTitle("lly_bank

  • java银行管理系统源码

    银行管理系统 (java实现),供大家参考,具体内容如下 1.创建一个封装类(Studentss) import javax.naming.Name; import javax.naming.NamingEnumeration; public class Studentss { //无参 public Studentss(){} //有参 public Studentss(String name,String account,int balance,String uesrpwds,String

  • Java实现银行存取款

    本文实例为大家分享了Java银行存取款的具体代码,供大家参考,具体内容如下 1.不加锁情况 运行结果: 代码:将加锁情况中加锁部分进行注释即可 2.加锁情况 运行结果 缓冲区代码 package Bank; import java.util.LinkedList; public class BankAccount { static double sum=1000; private LinkedList<Object> list = new LinkedList<>(); //存款

  • java实现银行家算法

    本文实例为大家分享了java实现银行家算法的具体代码,供大家参考,具体内容如下 import java.util.Arrays; import javax.swing.JOptionPane; public class Banker_Dijkstra { static int available[]={3,3,2}; //可利用资源数 static int max[][]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};; //每线程最大需求 static i

  • java实现简单银行管理系统

    本文实例为大家分享了java银行管理系统的具体代码,供大家参考,具体内容如下 账户类 package Account; public abstract class Account { private int id;//账号 private String password;//密码 private String name;//姓名 private String personId;//身份证号码 private String email;//邮箱 private double ceiling;//贷

  • Java实现的校验银行卡功能示例

    本文实例讲述了Java实现的校验银行卡功能.分享给大家供大家参考,具体如下: 步骤: 首先区分借记卡和信用卡,然后就是校验卡号,最后根据银联Bin确定什么银行,Bin之后就是归属地. 本文所有数据来源于网络,不一定保证正确和完整,这里仅仅作为教学使用. Java代码: package org.luozhuang.bankcard; public class checkBankCard { /* 当你输入信用卡号码的时候,有没有担心输错了而造成损失呢?其实可以不必这么担心, 因为并不是一个随便的信

随机推荐