用java编写多线程银行ATM 模拟程序
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用java编写多线程银行ATM 模拟程序相关的知识,希望对你有一定的参考价值。
要求:使用图形用户界面。当输入给定的账户和密码时,系统能登录ATM 柜员机系统,
并按照相应规则获得服务。
Ø ATM 系统分成服务器和客户机两个部分,服务器相当于银行的服务器,客户机相当于
ATM 自动取款机,该模拟程序需要分别实现服务器和ATM 客户机程序;
Ø ATM 账户及余额等信息可保存在mysql 数据库或文件中(推荐使用XML),若保存
在文件中,则服务器程序启动时应可从文件中装入;服务器通过网络对授权客户端提供
服务;
Ø 客户端为对ATM 机的模拟,可提供查询余额、存取款及修改密码等功能,要求如下:
n 每个ATM 有自己的ID、安装位置信息;
n 查询余额:初始余额为10000 元;
n ATM 取款:每次取款金额为100 元的整数倍,当日取款总额不超过5000 元,支取
金额不允许透支;
n 用户可查询交易明细,包括交易类型(存取款、转账等)、金额、时间和所在的ATM
机;
n ATM 存款:不能出现负存款;
n 修改密码:新密码长度不小于6 位,不允许出现6 位完全相同的情况,只有旧密码
正确,新密码符合要求,且两次输入相同的情况下才可以成功修改密码;
n 允许多个ATM 端同时操作不同的账户,相互不干扰,甚至允许多个ATM 端同时
对同一账户操作,且不出错。
PS:这不会是程序专题训练一吧。。。 参考技术A 主要是你要对数据库操作时,注意事务的处理,不然会出现逻辑错误,如:5个客户端同时取10000,怎么处理。如果你出钱的话,我可以帮你写一个。毕竟没有免费的午餐。联系邮箱:zhangxu1216@126.com 参考技术B 出钱让人弄吧!谁会免费给你 - -!!!本回答被提问者采纳
模拟ATM机银行系统
淄博汉企Java基础考核项目
模拟银行自助终端系统
一. 本系统模拟银行用户使用ATM机开户、查询、存款、取款功能,要求使用java语言编程实现。
说明:
1. 对于数据输入异常,可使用java异常处理机制进行处理。
2. 评分将以功能实现与代码规范性相结合的方式进行考核。
3. 如果对项目需求有疑问,可以随时以QQ留言方式联系我进行咨询。
4. 国庆放假期间,每天都有老师在公司值班,10月4日是我在公司值班,10月7日正常上班,欢迎大家到公司来做项目。
二. 项目功能要求:
项目开始运行显示主菜单为:
银行自助终端系统
****************************
0.------开户
1.------查询
2.------存款
3.------取款
4.------退出
****************************
请选择你要执行的功能:
此时,用户可以通过键盘输入选择自己要实现的功能,如果输入不是0,1,2,3,4,则系统提示:
你选择的菜单不存在!
请重新选择:
要求用户重新输入数据进行菜单选择!
当用户输入0时,则进入查询功能:系统提示:
****************************
你选择的为开户功能
请输入你的姓名:
此时用户需要输入姓名,输入完毕后系统提示:
请输入你的身份证号:
此时用户需要输入18位身份证号,输入完毕如果验证未通过要求继续输入,直到验证通过后系统提示:
请输入你的密码:
此时用户需要输入6位纯数字密码,输入完毕如果验证未通过要求继续输入,验证通过后系统提示:
开户成功,谢谢使用!
银行自助终端系统
****************************
0.------开户
1.------查询
2.------存款
3.------取款
4.------退出
****************************
请选择你要执行的功能:
当用户输入1时,则进入查询功能:系统提示:
****************************
你选择的为查询功能
请输入你要查询的卡号:
此时用户需要输入查询的卡号,系统对卡号进行检测,如果卡号不存在,则提示: 你输入的卡号不存在,请重新输入:
请输入你要查询的卡号:
要求重新输入卡号,当用户输入正确卡号后,则提示:
请输入你的密码:
此时用户需要输入6位纯数字密码,输入完毕如果验证未通过要求继续输入(最多3次),验证通过后系统将显示当前用户账号信息并进入主菜单:
你查询的账号信息为:
******************************
姓名 身份证号 卡号 金额
张三丰 420106198410112062 111111 12800.0
银行自助终端系统
****************************
0.------开户
1.------查询
2.------存款
3.------取款
4.------退出
****************************
请选择你要执行的功能:
当用户输入2时,则进入存款功能:系统提示:
****************************
你选择的为存款功能
请输入你要存款的卡号:
此时用户需要输入存款的卡号,系统对卡号进行检测,如果卡号不存在,则提示:
你输入的卡号不存在,请重新输入:
请输入你要存款的卡号:
要求重新输入卡号,当用户输入正确卡号后,则提示:
请输入你的密码:
此时用户需要输入6位纯数字密码,输入完毕如果验证未通过要求继续输入(最多3次),验证通过后系统将显示当前用户账号信息并进入主菜单:
你要存款的账号信息为:
******************************
姓名 身份证号 卡号 金额
张三丰 420106198410112062 111111 12800.0
请输入你要存入的金额:
此时要求用户输入存款金额,系统对金额进行判断,如果输入的数据小于等于0,则提示:
你输入的数据无效,系统将自动退出!谢谢使用
银行自助终端系统
****************************
0.------开户
1.------查询
2.------存款
3.------取款
4.------退出
****************************
请选择你要执行的功能:
如果用户输入数据合法,系统提示存款成功,并回到主菜单:
存款成功,谢谢使用!
银行自助终端系统
****************************
0.------开户
1.------查询
2.------存款
3.------取款
4.------退出
****************************
请选择你要执行的功能:
数据将存入用户账号,如果用户再次进行数据查询,则能看到已经改变后的账户金额。 (说明:本系统使用文件进行数据存储,因此如果用户重新启动程序,数据将从文件中读取重新初始化到内存!此功能选做,可参考对象的序列化和反序列化或JSON)
当用户输入3时,则进入取款功能:系统提示:
****************************
你选择的为取款功能 请输入你要取款的卡号:
此时用户需要输入取款的卡号,系统对卡号进行检测,如果卡号不存在,则提示:
你输入的卡号不存在,请重新输入:
请输入你要取款的卡号:
要求重新输入卡号,当用户输入正确卡号后,则提示:
请输入你的密码:
此时用户需要输入6位纯数字密码,输入完毕如果验证未通过要求继续输入(最多3次),验证通过后系统将显示当前用户账号信息并进入主菜单:
你要取款的账号信息为:
******************************
姓名 身份证号 卡号 金额
张三丰 420106198410112062 111111 12800.0
请输入你要取款的金额:
此时要求用户输入取款金额,系统对金额进行判断,如果输入的数据小于0或大于账号总金额,则提示:
你输入的数据无效,系统将自动退出!谢谢使用
银行自助终端系统
****************************
0.------开户
1.------查询
2.------存款
3.------取款
4.------退出
****************************
请选择你要执行的功能:
如果用户输入数据合法,系统提示取款成功,并回到主菜单:
取款成功,谢谢使用!
银行自助终端系统
****************************
0.------开户
1.------查询
2.------存款
3.------取款
4.------退出
****************************
请选择你要执行的功能:
数据将从用户账号扣出,如果用户再次进行数据查询,则能看到已经改变后的账户金额。
当用户输入4时,系统将退出。
三.设计要求
(一)包一:com.bank.unionpay 表示银联,在该包下添加:
- 表示银行卡的接口,包含查询余额,存款,取款等抽象方法。
- 表示ATM机的抽象类,使用银行卡类型的对象作为属性或参数,实现查询余额,存款,取款等实例方法,添加开户为抽象方法。
- 表示四大银行的枚举类型:包含ABC,ICBC,CCB,BOC;分别代表农行,工行,建行,中行。
(二)包二:com.bank.abc 表示农行,在该包下添加:
- 以单例模式定义银行类,包含属性:银行类型(枚举类型,常量=ABC),银行名称(String),银行卡列表(集合)等。
- 定义银行卡的实现类-储蓄卡,包含属性:银行类型(枚举类型=ABC),姓名,身份证号,卡号,密码,余额;实现查询余额,存款,取款等方法。
- 定义ATM机的子类,包含属性:银行类型(枚举类型,常量=ABC),实现开户方法,其中:只能开办储蓄卡,卡号为6位随机数字,自动产生。新开户的银行卡添加到银行的银行卡列表中。
- 定义储蓄卡的子类-信用卡,增加属性:透支额度,重写取款方法,控制最大取款金额不能大于余额+透支额度的和。
(三)包三:com.bank.test 表示测试,在该包下添加带main方法的测试类,实现项目要求的模拟ATM机的功能。
以下功能选做:
以单态模式实现工商银行,在测试类中默认添加多张银行卡,在农行的ATM机上实现跨行查询和存取款功能。
package com.bank.unionpay; //银行卡的接口 public interface I_yinhangka { //抽象方法 //public abstract默认修饰抽象的 public abstract void cxyue();//查询余额 void cunkuan();//存款 void qukuan();//取款 void accound();//账户 }
package com.bank.unionpay; public abstract class Atm implements I_yinhangka { String leixing;//银行卡类型 String accound;//账户 double qukuan;//取款 double cunkuan;//存款 double cxyue ;//余额 String name; String sfzheng;//省份证号 public Atm(String name,String sfzheng,String accound, double cxyue ) { super(); this.accound = accound; this.cxyue = cxyue; this.name = name; this.sfzheng = sfzheng; } public Atm() { super(); } @Override public void cxyue() { // 查询余额 cxyue-=qukuan; cxyue+=cunkuan; System.out.println("您的余额="+cxyue); } @Override public void cunkuan() { // 存款 cxyue+=cunkuan; System.out.println("存款成功,您的存款金额为"+cunkuan); System.out.println("本次操作后您的余额为:"+cxyue); } @Override public void qukuan() { // 取款 cxyue-=qukuan; if(cxyue>=0) { System.out.println("取款成功,本次取款金额= "+qukuan); System.out.println("本次操作后您的余额= "+cxyue); } else { System.out.println("余额不足,无法取款"); } } @Override public void accound() { // 账户 } //声明成员方法 public double qukuan(double qukuan)//取款 { cxyue-=qukuan; if(cxyue>=0) { System.out.println("取款成功,本次取款金额= "+qukuan); System.out.println("本次操作后您的余额= "+cxyue); } else { System.out.println("余额不足,无法取款"); } return qukuan; } public double cunkuan(double cunkuan)//存款 { cxyue+=cunkuan; System.out.println("存款成功,您的存款金额为"+cunkuan); System.out.println("本次操作后您的余额为:"+cxyue); return cunkuan; } public double cxyue(double cxyue) { cxyue-=qukuan; cxyue+=cunkuan; System.out.println("您的余额="+cxyue); return cxyue; } //添加开户的抽象方法 public abstract void kaihu(); }
package com.bank.unionpay; //银行枚举类型 public enum Leixing { ABC("农行"),ICBC("工行"),CCB("建行"),BOC("中行"); private final String leixing; public String getLeixing() { return this.leixing; } //构造方法 private Leixing(String leixing) { this.leixing=leixing; } }
package com.bank.abc; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.bank.unionpay.Leixing; //单利模式 public class Bank { private Bank()//禁止外部访问构造方法 { } private static Bank bank=new Bank();//内部产生唯一实例 public static Bank getBank()//开放一个方法给调用者返回这个实例 { return bank; } final Leixing lx=Leixing.ABC;//农行类型 private String yhName;//银行名称 public List <String>card=new ArrayList<>();//银行卡列表 public Map<String, CxCard > account=new HashMap<>();//账号储蓄卡集合 }
package com.bank.abc; import java.util.Random; import java.util.Scanner; import com.bank.unionpay.Atm; import com.bank.unionpay.Leixing; public class Atm2 extends Atm { public CxCard cx=new CxCard();//调用map储蓄卡的信息的对象 public Atm2(String name, String sfzheng, String accound, double cxyue) { super(name, sfzheng, accound, cxyue); // TODO 自动生成的构造函数存根 } public Atm2() { // TODO 自动生成的构造函数存根 super(); } final Leixing lx = Leixing.ABC; @Override public void kaihu()// 实现开户 { System.out.println("您选择的为开户功能"); Scanner sc0=new Scanner(System.in); System.out.println("请输入姓名"); cx.name=sc0.nextLine(); for(int i=1;i>0;i++) { System.out.println("请输入身份证号"); cx.sfzheng=sc0.nextLine(); if(cx.sfzheng.length()==18)//判断身份证 { for(int j=1;j>0;j++) { System.out.println("请输入密码"); String mm="\\\\d{6}";//6位数字正则表达式 cx.password=sc0.nextLine(); if(cx.password.matches(mm)) { cx.setPassword(cx.password);//密码 Random ra=new Random();//随机生成6位卡号 int[] ch=new int[6]; StringBuilder str=new StringBuilder(); String s; for(int k=0;k<6;k++) { ch[k]=ra.nextInt(9);//0-9 } for(Integer c:ch) { str.append(c.toString());//遍历 拼接6位数字 } s=str.toString(); cx.setCairNumber(s);//写入卡号 Bank.getBank().card.add(cx.getCairNumber());//将生成的储蓄卡号存到银行的银行卡列表中 Bank.getBank().account.put(cx.getCairNumber(), cx); //id+储蓄卡对象 System.out.println("开户成功"); System.out.println("您的账号为: "+cx.getCairNumber()); break; } else { System.out.println("请输入6位纯数字密码"); } } break; } else { System.out.println("请重新输入身份证号"); } } } }
package com.bank.abc; import java.util.Scanner; import com.bank.unionpay.Leixing; //储蓄卡 public class CxCard { //属性 final Leixing lx=Leixing.ABC; String name;//姓名 String sfzheng;//身份证号 String cairNumber;//卡号 String password;//密码 double cxyue ;//余额 //生成卡号的get set方法 public String getCairNumber() { return cairNumber; } public void setCairNumber(String cairNumber) { this.cairNumber = cairNumber; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSfzheng() { return sfzheng; } public void setSfzheng(String sfzheng) { this.sfzheng = sfzheng; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public double getCxyue() { return cxyue; } public void setCxyue(double cxyue) { this.cxyue = cxyue; } public CxCard(String name, String sfzheng, String cairNumber, String password, double cxyue) { super(); this.name = name; this.sfzheng = sfzheng; this.cairNumber = cairNumber; this.password = password; this.cxyue = cxyue; } @Override public String toString() { return "姓名:" + name + "\\n"+" 身份证:" + sfzheng + "\\n"+"卡号: " + cairNumber +"\\n"+ " 余额:" + cxyue; } public CxCard() { // TODO 自动生成的构造函数存根 } //声明成员方法 public void qukuan()//取款 { if(true) { System.out.println("您选择的为取款功能"); for(int i=1;i>0;i++) { Scanner sc1=new Scanner(System.in); System.out.println("请输入您要取款的卡号"); cairNumber=sc1.nextLine(); if(Bank.getBank().account.containsKey(getCairNumber()))//判断卡号是否存在 { for(int h=0;h<4;h++) { h=h+1; System.out.println("请输入密码"); String passwordshuru=sc1.nextLine(); if(passwordshuru.equals(Bank.getBank().account.get(cairNumber).getPassword()))//判断密码 { System.out.println("您要取款的账号信息为:"); System.out.println("****************"); //遍历卡号 for(String k:Bank.getBank().account.keySet()) { System.out.println("账号: "+k); //通过k便利values的账户信息 System.out.println(Bank.getBank().account.get(k)); } System.out.println("请输入您要取款的金额"); Scanner qukuan=new Scanner(System.in); double qk=qukuan.nextDouble(); if(qk>=0) { //通过k获取v里面的余额,减去取款金额生成余额 cxyue=Bank.getBank().account.get(cairNumber).getCxyue() -qk; System.out.println(cxyue); if(cxyue>=0) { Bank.getBank().account.get(cairNumber).setCxyue(cxyue); System.out.println("取款成功,本次取款金额= "+qk); System.out.println("本次操作后您的余额= "+Bank.getBank().account.get(cairNumber).getCxyue()); } } else { System.out.println("余额不足,无法取款"); } break; } else { System.out.println("请重新输入密码,还剩"+(4-h)+"次"); } } break; } } } } public void cunkuan()//存款 { if(true) { System.out.println("您选择的为存款功能"); for(int i=1;i>0;i++) { Scanner sc1=new Scanner(System.in); System.out.println("请输入您要存款的卡号"); cairNumber=sc1.nextLine(); if(Bank.getBank().account.containsKey(getCairNumber()))//判断卡号是否存在 { for(int h=0;h<4;h++) { h=h+1; System.out.println("请输入密码"); String passwordshuru=sc1.nextLine(); //判断如果输入的密码和通过k找到v里面存的密码一致,输出信息 if(passwordshuru.equals(Bank.getBank().account.get(cairNumber).getPassword()))//判断密码 { System.out.println("您要存款的账号信息为:"); System.out.println("****************"); //遍历卡号 for(String k:Bank.getBank().account.keySet()) { System.out.println("账号: "+k); System.out.println(Bank.getBank().account.get(k)); } System.out.println("请输入您要存入的金额"); Scanner cunkuan1=new Scanner(System.in); double ck=cunkuan1.nextDouble(); if(ck>=0) { cxyue+=ck; System.out.println("存款成功,您的存款金额为"+ck); //把操作后的余额写进集合 Bank.getBank().account.get(cairNumber).setCxyue(cxyue); System.out.println("本次操作后您的余额为:"+Bank.getBank().account.get(cairNumber).getCxyue()); } else { System.out.println("你输入的数据无效,系统将自动退出!谢谢使用"); } break; } else { System.out.println("请重新输入密码,还剩"+(4-h)+"次"); } } break; } else { System.out.println("该卡号不存在,请重新输入要查询的卡号"); } } } } public void cxyue()//查询 { if(true) { System.out.println("您选择的为查询功能"); for(int i=1;i>0;i++) { Scanner sc1=new Scanner(System.in); System.out.println("请输入您要查询的卡号"); cairNumber=sc1.nextLine(); if(Bank.getBank().account.containsKey(getCairNumber()))//判断卡号是否存在 { for(int h=0;h<4;h++) { h=h+1; System.out.println("请输入密码"); String passwordshuru=sc1.nextLine(); //判断密码 if(passwordshuru.equals(Bank.getBank().account.get(cairNumber).getPassword())) { System.out.println("您查询的账号信息为:"); System.out.println("****************"); //遍历卡号 for(String k:Bank.getBank().account.keySet()) { System.out.println("账号: "+k); //通过k遍历values的信息 System.out.println(Bank.getBank().account.get(k)); } break; } else { System.out.println("请重新输入密码,还剩"+(4-h)+"次"); } } //System.out.println("密码输入超过三次,自动退出系统"); break; } else { System.out.println("该卡号不存在,请重新输入要查询的卡号"); } } } } }
package com.bank.test; import java.util.Scanner; import com.bank.abc.Atm2; import com.bank.abc.Bank; import com.bank.abc.CxCard; import com.bank.unionpay.Atm; import com.bank.unionpay.Leixing; import com.bank.unionpay.Zhujiemian; public class A { public static void main(String[] args) throws Exception { // TODO 自动生成的方法存根 Leixing[] l= Leixing.values(); for(Leixing x:l) { System.out.println("银行卡类型的枚举="+x); } System.out.println("*************************"); for(int i=1;i>0;i++) { Zhujiemian zjm=new Zhujiemian(); zjm.zhujiemian(); try { Scanner sc=new Scanner(System.in); int in=sc.nextInt(); if(in==0||in==1||in==2||in==3||in==4) { if(in==0) {//测试开户 Atm2 a2=new Atm2(); a2.kaihu(); continue; } //查询 if(in==1) { Atm2 a2=new Atm2(); a2.cx.cxyue(); continue; } if(in==2) { //存款 Atm2 a2=new Atm2(); a2.cx.cunkuan(); continue; } if(in==3) { //取款 Atm2 a2=new Atm2(); a2.cx.qukuan(); continue; } if(in==4) { //退出 System.out.println("系统即将推出"); break; } } else { System.out.println("该菜单不存在"); } } catch(Exception e) { System.out.println("输入有误,自动退出系统"); } } } }
以上是关于用java编写多线程银行ATM 模拟程序的主要内容,如果未能解决你的问题,请参考以下文章