文件及输入输出流模拟ATM机

Posted 知止

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文件及输入输出流模拟ATM机相关的知识,希望对你有一定的参考价值。

题目:两部分要求都要实现。

一、ATM机的账户记录Account有账户的唯一性标识(11个长度的字符和数字的组合),用户的姓名,操作日期(Date),操作类型,账户密码(六位的数字,可以用0开头),当前的余额(可以为0)。 模拟ATM的功能设计,用户插卡后显示选择语言界面,输入密码界面,用户输入正确密码(用户输入错误密码,则提示该卡已被锁定,无法操作),则弹出选择界面:存款、取款、转账汇款、修改密码、查询余额。 选择“取款”,则显示100元、500元、1000元、1500元、2000元、5000元、其他金额、退卡、返回操作供用户选择; 选择“存款”,则提示用户输入存款金额,修改余额; 选择“转账”,则提示用户输入转账行号、转账金额,并提示转账成功。 

 

二、假定银行的一个存取款系统有两类客户,一类是现金用户,一类是信用卡用户。银行对每个客户都要登记其姓名name,并为之分配一个唯一的账户号码aid,现金用户还要记录其卡的类型(工资卡、借记卡、理财卡),而信用卡用户则根据其信用级别有一定的透支限额lineOfCredit(A级10000元、B级5000元、C级2000元、D级1000元)。每种客户都可以实现存deposit、取withdraw、和查询余额getBalance,信用卡用户还可以查询透支情况findOverdraw。对于现金用户,每次取款操作只能在账户实际额度balance内操作,允许现金用户改变自己的帐户类型。

(1) 分析有哪些属性和方法可以作为两个子类的共同属性和方法,然后写出抽象类

Account的定义。

(2) 分析CashAccount有那些新增的属性和方法,定义一个继承于Account的子类

CashAccount。

(3) 分析CreditAccount有那些新增的属性和方法,然后定义一个继承于Account

的子类CreditAccount,添加增加的属性和方法。

(4) 请按照要求编写一个程序Test,用你所定义的类完成下列业务操作。

1) 用 Account 作为类型定义两个变量 credit 和 debit,分别引用

CreditAccount和CashAccount的对象,并完成存款500元的操作。

第 3 页 共 5 页

2) 每个对象完成取款200元的操作后再次取款400元,请输出各自的余额。

3) 可以通过credit查看引用对象的透支额吗,如果不能,怎样修改可以查

看?

(5) 添加一个取款异常WithdrawException,请定义异常类WithdrawException,

要求:

1) 异常对象记录取款发生时的帐户余额、取款额还有取款人。

2) 覆盖继承于超类的方法getMessage(),按以下格式返回信息:

取款人,账号余额,取款额,原因:透支。

3) 修改CashAccount的取款方法,当用户取款超出额度时,抛出异常。

4) 编写一个可执行类Test,创建一个CashAccount的对象,其初始余额为500,

连续取款2次,每次300,写出运行结果。

(6) 构建客户基本信息表(ClientInfoTable.txt)和账户流水表(BankInfoTable

.txt)两个数据文件;

客户基本信息表存储信息包括账户号码aid(唯一性),姓名name,,客户

类型(现金卡用户或信用卡用户),卡类型(工资卡、借记卡、理财卡(客户

类型为现金卡时有效)),信用卡透支类型(A级10000元、B级5000元、C级

2000元、D级1000元),卡余额,日期;

账户流水表存储信息包括序号(自动增 1,并保持唯一),账户号码,姓

名,日期,流水类型(存款、取款、透支取款),金额。

(7) 增加查询功能,可以查询账号或姓名查询客户信息,可以查询账号或姓名查询

流水信息。

(8) 增加统计功能,可以根据账号,起始日期、终止日期、流水类型,统计账号流

水信息。

***************************************************************************************************************

拿到这个题目,我开始分析出:

两类账户及其操作可以由不同的类来表示;

存款、转账、取款等操作实际上对文件的读写、修改等操作;

增加的统计功能实际上是考察如何对文件进行统一格式的读写操作。

画上代码的继承关系和类包含的方法图:

前两段代码就是展开写两个类CashAccount(现金用户)和CreditAccount(信用卡用户)类。

第一段代码:

  1 package ATM;
  2 import java.io.*;
  3 import java.util.Calendar;
  4 import java.util.GregorianCalendar;
  5 import java.util.Scanner;
  6 import java.util.StringTokenizer;
  7 
  8 abstract class Account1{
  9     //抽象类,现金类用户和信用卡用户父类。
 10     String aid,name;
 11     double balance;//余额
 12     public void deposit(){}//存款
 13     public void withdraw(){}//取款
 14     public void getBalance(){}//查询余额
 15     public void getMssage(){}//查询信息
 16 }
 17 public class CashAccount extends Account1{
 18     String cardtype;//卡的类型
 19     CashAccount(){
 20         this.aid="";
 21         this.name="";
 22         this.balance=0;
 23     }
 24     CashAccount(String a,String b,double c,String d){
 25         this.aid=a;
 26         this.name=b;
 27         this.balance=c;
 28         this.cardtype=d;
 29     }
 30     /*
 31      *存款方法,写操作
 32      */
 33     public void deposit(PrintWriter in,int i){
 34         Scanner s1=new Scanner(System.in);
 35         System.out.println("请输入要存入的数额");
 36         double s=s1.nextDouble();
 37         balance=balance+s;
 38         System.out.println("存款成功!您的余额为"+balance);
 39         this.Writerecord(in, "存款", s,i);//调用函数
 40     }
 41     /*
 42      * 取款方法,写操作
 43      */
 44     public void withdraw(PrintWriter in,int i){
 45         System.out.println("请输入要取的数额");
 46         Scanner S=new Scanner(System.in);
 47         double s=S.nextDouble();
 48         try{
 49         if(balance-s>0){
 50             balance=balance-s;
 51             System.out.println("取款成功!您的余额为"+balance);
 52             this.Writerecord(in, "取款", -s,i);
 53         }
 54         else
 55             throw new WithdrawException("余额不足!重新输入!");
 56         }catch(WithdrawException e){System.out.println(e);
 57         this.getMssage(s);
 58         withdraw(in,i);}    
 59     }
 60     /*
 61      显示余额方法,写入操作
 62      */
 63     public void getBalance(PrintWriter in,int i){
 64         System.out.println("您的余额为"+balance);
 65         this.Writerecord(in, "查询余额", 0,i);
 66     }
 67     /*
 68      改变卡类型方法
 69      */
 70     public void Changetype(PrintWriter in,int i){
 71         System.out.println("您当前的卡类型为"+cardtype);
 72         System.out.println("选择您需要的卡类型\\n1.工资卡\\n2.借记卡\\n3.理财卡");
 73         Scanner S=new Scanner(System.in);
 74         int s=S.nextInt();
 75         switch(s){
 76         case 1:cardtype="工资卡";break;
 77         case 2:cardtype="借记卡";break;
 78         case 3:cardtype="理财卡";break;
 79         }
 80         this.Writerecord(in, "变更卡的类型", 0,i);
 81     }
 82     /*
 83      * 显示信息方法*/
 84     public void getMssage(double a){
 85         System.out.println("取款人"+name+"\\n"+"账户余额"+balance+"\\n"+"取款额"+a+"\\n"+"原因:透支");
 86     }
 87     /*
 88      * 写文件的方法
 89      * @参数 out在print writer*/
 90      public void writeData(PrintWriter out) throws IOException
 91        {
 92           out.println(aid + "|"
 93              + name + "|"
 94              + cardtype + "|"
 95              + Double.toString(balance));
 96        }
 97      /*
 98       * 独文件的方法
 99       * @ in的参数在buffer
100       */
101      public void readData(BufferedReader in) throws IOException
102        {
103           String s = in.readLine();
104           StringTokenizer t = new StringTokenizer(s, "|");
105           aid=t.nextToken();
106           name = t.nextToken();
107           cardtype=t.nextToken();
108           balance=t.countTokens();
109        }
110      /*
111       * 写操作记录的方法
112       * 参数来自主类的文件路径和print writer
113       * */
114      public  void Writerecord(PrintWriter in,String op,double a,int i) {
115          String months[] = { 
116                  "Jan", "Feb", "Mar", "Apr", 
117                  "May", "Jun", "Jul", "Aug",
118                  "Sep", "Oct", "Nov", "Dec"};
119                  //初始化当前时间并在后续写入文件
120                  Calendar calendar = Calendar.getInstance();                
121          in.println(String.valueOf(i)+"|"+aid + "|"
122              + name + "|"+String.valueOf(calendar.get(Calendar.YEAR))+
123                   "|"+String.valueOf(months[calendar.get(Calendar.MONTH)])+"|"+
124             String.valueOf(calendar.get(Calendar.DATE))
125              + "|"+String.valueOf(calendar.get(Calendar.HOUR))+"|"+
126              String.valueOf(calendar.get(Calendar.MINUTE))
127              +"|"+op+"|"
128              + Double.toString(a));
129         }
130 }
131 class WithdrawException extends Exception{
132     WithdrawException(String s){super(s);}
133 }
View Code

第二段:

  1 package ATM;
  2 import java.io.*;
  3 import java.util.Calendar;
  4 import java.util.GregorianCalendar;
  5 import java.util.Scanner;
  6 import java.util.StringTokenizer;
  7 
  8 public class CreditAccount extends Account1 {
  9     double lineOfCredit;//信用等级对应的可透支额
 10     String creditrate;//信用等级
 11     CreditAccount(){
 12         this.aid="";
 13         this.name="";
 14         this.balance=0;
 15         this.lineOfCredit=0;
 16         this.creditrate="A";
 17     }
 18     CreditAccount(String a,String b,double c,String d){
 19         this.aid=a;
 20         this.name=b;
 21         this.balance=c;
 22         this.creditrate=d;
 23         switch(d){
 24         case "A":lineOfCredit=10000;break;
 25         case "B":lineOfCredit=5000;break;
 26         case "C":lineOfCredit=2000;break;
 27         case "D":lineOfCredit=1000;break;
 28         }
 29     }
 30     /*
 31      * 存款方法
 32      * */
 33     public void deposit(PrintWriter in,int i){
 34         System.out.println("请输入要存入的数额");
 35         Scanner S=new Scanner(System.in);
 36         double s=S.nextDouble();
 37         balance=balance+s;
 38         System.out.println("存款成功!您的余额为"+balance);
 39         this.Writerecord(in, "存款", s,i);
 40     }
 41     /*
 42      * 取款方法*/
 43     public void withdraw(PrintWriter in,int i){
 44         System.out.println("请输入要取的数额");
 45         Scanner S=new Scanner(System.in);
 46         double s=S.nextDouble();
 47         try{
 48         if(balance-s>0){
 49             balance=balance-s;
 50             System.out.println("取款成功!您的余额为"+balance);
 51             this.Writerecord(in, "取款", -s,i);
 52         }
 53         else
 54             if(lineOfCredit+balance-s>0){
 55                 balance=balance-s;
 56                 lineOfCredit=lineOfCredit+balance;
 57                 System.out.println("您的余额为"+balance+"您的可透支余额为"+lineOfCredit);
 58             }
 59             else
 60             throw new WithdrawException("余额不足!重新输入!");
 61         }catch(WithdrawException e){System.out.println(e);
 62         this.getMssage(s);
 63         withdraw(in,i);}    
 64     }
 65     /*显示余额方法
 66      * */
 67     public void getBalance(PrintWriter in,int i){
 68         System.out.println("您的余额为"+balance);
 69         this.Writerecord(in, "查询余额", 0,i);
 70     }
 71     /*显示可透支余额方法
 72      * */
 73     public void findOverdraw(PrintWriter in,int i){
 74         System.out.println("您的可透支余额为"+lineOfCredit);
 75         this.Writerecord(in, "查询可透支余额", 0,i);
 76     }
 77     /*显示信息方法
 78      * */
 79     public void getMssage(double a){
 80         System.out.println("取款人"+name+"\\n"+"账户余额"+balance+"\\n"+"取款额"+a+"\\n"+"原因:透支");
 81     }
 82     /*
 83      * 写文件的方法
 84      * @参数 out在print writer*/
 85      public void writeData(PrintWriter out) throws IOException
 86        {
 87           out.println(aid + "|"
 88              + name + "|"+ creditrate + "|"
 89              + Double.toString(lineOfCredit) + "|"
 90              + Double.toString(balance));
 91        }
 92      /*
 93       * 独文件的方法
 94       * @ in的参数在buffer
 95       */
 96      public void readData(BufferedReader in) throws IOException
 97        {
 98           String s = in.readLine();
 99           StringTokenizer t = new StringTokenizer(s, "|");
100           aid=t.nextToken();
101           name = t.nextToken();
102           creditrate=t.nextToken();
103           lineOfCredit=Double.parseDouble(t.nextToken());
104           balance=Double.parseDouble(t.nextToken());
105        }
106      /*
107       * 写操作记录的方法
108       * 参数来自主类的文件路径和print writer
109       * */
110      public  void Writerecord(PrintWriter in,String op,double a,int i) {
111          String months[] = { 
112                  "Jan", "Feb", "Mar", "Apr", 
113                  "May", "Jun", "Jul", "Aug",
114                  "Sep", "Oct", "Nov", "Dec"};
115                  //初始化当前时间并在后续写入文件
116                  Calendar calendar = Calendar.getInstance();                
117          in.println(String.valueOf(i)+"|"+aid + "|"
118              + name + "|"+String.valueOf(calendar.get(Calendar.YEAR))+
119                   "|"+months[calendar.get(Calendar.MONTH)]+"|"+
120              String.valueOf(calendar.get(Calendar.DATE))
121              + "|"+String.valueOf(calendar.get(Calendar.HOUR))+"|"+
122              String.valueOf(calendar.get(Calendar.MINUTE))+"|"+
123              op+"|"+Double.toString(a));
124         }
125 }
View Code

第三段代码包含一个Record类,其中包含读取记录和统计以及重写的ToString方法。

第三段:

package ATM;
import java.io.*;
import java.util.Scanner;
import java.util.StringTokenizer;
public class Record {
String aid,name,operation;
int number,year,month,data,hour,minute;
double money;
/*
 * 读取操作记录的方法*/
public void readData(BufferedReader in)throws IOException{
    int i=0;
    String s = in.readLine();
    StringTokenizer t = new StringTokenizer(s, "|");
    number=Integer.parseInt(t.nextToken());
    aid=t.nextToken();
    name = t.nextToken();
    year=Integer.parseInt(t.nextToken());
    switch(t.nextToken()){
    case "Jan":i=1;break;
    case "Feb":i=2;break;
    case "Mar":i=3;break;
    case "Apr":i=4;break;
    case "May":i=5;break;
    case "Jun":i=6;break;
    case "Jul":i=7;break;case "Aug":i=9;break;
    case "Sep":i=9;break;case "Oct":i=10;break; case"Nov":i=11;break;case "Dec":i=12;break;
    }
    month=i;
    data=Integer.parseInt(t.nextToken());
    hour=Integer.parseInt(t.nextToken());
    minute=Integer.parseInt(t.nextToken());
    operation=t.nextToken();
    money=Double.parseDouble(t.nextToken());
}
/*
 * 统计操作记录的方法
 * 参数分别为 
 * 记录数组 
 * 1代表按aid查询 2代表按日期查询
 * s表示aid*/
public void Sort(Record[] a,int i,String s){
    if(i==1)//按照aid查询所有记录
    {
        System.out.println("您的操作记录为");
        for (Record e : a)
        if(e.aid.equals(s))
            System.out.println(e);
    }
    else if(i==2)//按照aid和日期查找记录
    {
        System.out.println("请输入您想查找的时间区间");
        Scanner q=new Scanner(System.in);
        System.out.println("请输入您想查找的起始年,格式为2016");
        int tyear=q.nextInt();
        System.out.println("请输入您想查找的起始月,格式为3");
        int tmonth=q.nextInt();
        System.out.println("请输入您想查找的起始日期,格式为1");
        int tdata=q.nextInt();
        System.out.println("请输入您想查找的终止年,格式为2016");
        int tyeare=q.nextInt();
        System.out.println("请输入您想查找的终止月,格式为3");
        int tmonthe=q.nextInt();
        System.out.println("请输入您想查找的终止日期,格式为1");
        int tdatae=q.nextInt();
        for (Record e : a)
            if(e.aid.equals(s)&&e.year>=tyear&&e.year<=tyeare&&e.month>=tmonth&&e.month<=tmonthe
            &&e.data>=tdata&&e.data<=tdatae)
                System.out.println(e);
        q.close();
    }
}
//将对象转换为字符串
public String toString()
{
   return getClass().getName()
      + "[number="+String.valueOf(number)+" aid=" + aid
      + ",name=" + name+" "+String.valueOf(year)+"/"+String.valueOf(month)+"/"+
      String.valueOf(data)+"/"+String.valueOf(hour)+"/"+String.valueOf(minute)+"/"
      + "操作:" + operation+" 金额: "+String.valueOf(money)
      + "]";
}
}
View Code

第四段代码就是主类,其中包含界面控制、等操作。

第四段:

  1 package ATM;
  2 import java.io.*;
  3 import java.util.Scanner;
  4 
  5 public class Login {
  6     public static void main(String[] args){
  7         int number=1;
  8         CashAccount[] a=new CashAccount[3];
  9         CreditAccount[] b=new CreditAccount[3];
 10         a[0]=new CashAccount("01","a",100,"借记卡");
 11         a[1]=new CashAccount("02","b",100,"借记卡");
 12         a[2]=new CashAccount("03","c",100,"借记卡");
 13         b[0]=new CreditAccount("04","d",100,"A");
 14         b[1]=new CreditAccount("05","e",100,"A");
 15         b[2]=new CreditAccount("06","f",100,"A");
 16          try
 17           {
 18              // 写入文件,从末尾写入  分别写现金操作和信用卡操作
 19              //不论记录数据还是记录操作,都按现金和信用卡分别建立文件 1对应信用卡
 20              PrintWriter out = new PrintWriter(new FileWriter("C://ClientInfoTable.txt"),true);
 21              PrintWriter out1 = new PrintWriter(new FileWriter("C://ClientInfoTable1.txt"),true);
 22              PrintWriter in = new PrintWriter(new FileWriter("C://BankInfoTable.txt",true));
 23              PrintWriter in1 = new PrintWriter(new FileWriter("C://BankInfoTable1.txt",true));
 24              in.println("序号"+"|"+"卡号"+"|"+"姓名"+"|"+"年"+"|"+"月"+"|"+"日"+"|"+"时"+"|"+"分"+"|"+"操作类型"+"|"+"金额");
 25              in1.println("序号"+"|"+"卡号"+"|"+"姓名"+"|"+"年"+"|"+"月"+"|"+"日"+"|"+"时"+"|"+"分"+"|"+"操作类型"+"|"+"金额");
 26              out.println("卡号"+"|"+"姓名"+"|"+"卡类型"+"|"+"余额");
 27              out1.println("卡号"+"|"+"姓名"+"|"+"信用等级"+"|"+"可透支额"+"|"+"余额"); 
 28              writeDatacash(a, out);
 29              writeDatacredit(b, out1);
 30              do{
 31                  try{
 32                      System.out.print("请选择用户类型\\t1.现金卡\\t2.信用卡");
 33                      Scanner s=new Scanner(System.in);
 34                      int i=s.nextInt();
 35                      if(i==1)
 36                          {showface(a[i],in,number);
 37                          in.flush();}
 38                      else if(i==2)
 39            

以上是关于文件及输入输出流模拟ATM机的主要内容,如果未能解决你的问题,请参考以下文章

用java编写的ATM机源代码

ATM

用java做一个简易的ATM机具体流程在下面

ATM java

模拟ATM机系统

语言模拟ATM自动取款机系统