个人银行账户管理系统课程设计报告

一、课程设计要求与目的

  1. 模仿个人银行账户管理系统的C++版本(第4章-第9章),使用Java语言重新实现该系统,比较C++与Java在实现上的异同,熟练掌握Java基础及语法。
  2. 根据业务需求的增加,对个人银行账户管理系统进行功能上的完善,利用面向对象的思想对代码进行重构,体会抽象、封装、继承、多态等特性在实际系统中的应用,掌握构造可复用、可扩展、可维护软件的基本技能。

二、课程版本记录 

1.个人个人银行账户管理系统版本0.1(对应第4章记录)

 系统需求

一个活期储蓄账户包括 账号(id) 、 余额(balance) 、 年利率(rate) 等信息,还包括 显示账户信息(show) 、 存款(deposit) 、取款(withdraw) 、 结算利息(settle) 等操作。

 系统设计

设计一个 类 Bank , 其数据成员为 id, balance, rate , 类的方法有 show(), deposit(), withdraw(), settle()

 系统实现

数据成员

class bank{
    int id;				//账号
    double balance;		//余额
    double rate;		//存款的年利率
    int lastDate;		//上次变更余额的时期
    double accumulation;	//余额按日累加之和
}

类中方法

class bank{

    public bank(int _date,int _id,double _rate){
        lastDate=_date;
        id=_id;
        rate=_rate;
    }

    //记录一笔帐,date为日期,amount为金额,desc为说明
    void record(int date, double amount){
        accumulation = accumulate(date);
        lastDate = date;
        amount = Math.floor(amount * 100 + 0.5) / 100;	//保留小数点后两位
        balance += amount;
        System.out.println(date+"\t#"+id+"\t"+amount+"\t"+balance);
    }

    //获得到指定日期为止的存款金额按日累积值
    final double accumulate(int date) {
        return accumulation + balance * (date - lastDate);
    }

    int getId() { return id; }
    double getBalance() { return balance; }
    double getRate() { return rate; }

    //存入现金
    void deposit(int date, double amount){
        record(date, amount);
    }
    //取出现金
    void withdraw(int date, double amount){
        if (amount > getBalance())
            System.out.println("Error: not enough money");
        else
            record(date, -amount);
    }
    //结算利息,每年1月1日调用一次该函数
    void settle(int date){
        double interest = accumulate(date) * rate / 365;	//计算年息
        if (interest != 0)
            record(date, interest);
        accumulation = 0;
    }
    //显示账户信息
    void show(){
        System.out.println("#"+id+"\tBalance:"+balance);
    }

}

系统测试

 个人银行账户管理系统课程设计报告

体会心得

 java 在输出浮点数时,整数不经过处理时会输出小数点后一位的零,而 c++ 的输出会舍弃。java 在实例化对象时的语法与 c++ 相比有些不同,例如 className c; 在 c++ 中即表示实例化一个对象,而在 java 中虽然表达相同,但实际仅仅是对象的声明,此时并没有实例化真正的对象,同时 java 实例化对象时需要使用关键字 new

2.个人个人银行账户管理系统版本0.2(对应第5章记录)

系统需求

相较于上一版本,在活期账户中添加一个用来记录各个账户的总金额的功能,同时可以获取这个总金额(total)。

系统设计

在Account类中添加一个静态数据成员 total , 用来记录各个账户的总金额,并为其增加相应的静态成员方法 getTotal 用来对其进行访问。

系统实现

增加如下代码

private static double total=0;	//所有账户的总金额

public static double getTotal() { return total; }

系统测试

个人银行账户管理系统课程设计报告

体会心得

类中的静态变量只占用该类的一个空间,可以当作本类的一个计数器。静态数据成员仅由静态成员方法来访问。

3.个人个人银行账户管理系统版本0.3(对应第6章记录)

系统需求

新增一个日期类Date,具有输出当前日期,判断闰年,计算两个日期值之间相差天数等功能

增加了报告错误信息

系统设计

银行账户用字符串进行表示

用desc为账目进行了说明

新添Date类

系统实现

新增类

public class Date {
    private final int[] DAYS_BEFORE_MONTH={0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
    private int year;		//年
    private int month;		//月
    private int day;		//日
    private int totalDays;	//该日期是从公元元年1月1日开始的第几天

    public Date(int year, int month, int day){}//用年、月、日构造日期
    public final int getYear()  {  }
    public final int getMonth()  {  }
    public final int getDay()  { }
    public final int getMaxDay() {}		//获得当月有多少天
    public final boolean isLeapYear()  {}	//判断当年是否为闰年
    public final void show() {}//输出当前日期
    //计算两个日期之间差多少天
    public final int distance(final Date date)  {}
}

Account的改动

    private String id;		//帐号
    private Date lastDate;		//上次变更余额的时期

    //记录一笔帐,date为日期,amount为金额,desc为说明
    private void record(final Date date, double amount, final String desc){
        accumulation = accumulate(date);
        lastDate = date;
        amount = Math.floor(amount * 100 + 0.5) / 100;	//保留小数点后两位
        balance += amount;
        total += amount;
        date.show();
        System.out.println("\t#"+id+"\t"+amount+"\t"+balance+"\t"+desc);
    }
    //报告错误信息
    private final void error(final String msg){
        System.out.println("Error(#"+id+"): "+msg);
    }    
    //存入现金
    public void deposit(final Date date, double amount, final String desc){
        record(date, amount, desc);
    }
    //取出现金
    public void withdraw(final Date date, double amount, final String desc){
        if (amount > getBalance())
            error("not enough money");
        else
            record(date, -amount, desc);
    }
    //结算利息,每年1月1日调用一次该函数
    public void settle(final Date date){
        double interest = accumulate(date) * rate	//计算年息
                / date.distance(new Date(date.getYear()-1,1,1));
        if (interest != 0)
            record(date, interest, "interest");
        accumulation = 0;
    }

系统测试

个人银行账户管理系统课程设计报告

体会心得

组合类方便了一些功能的实现和管理,Date类使得有关日期的操作可以和Account类的实现相互独立,无需关心Date类的具体实现

4.个人个人银行账户管理系统版本0.4(对应第7章记录)

系统需求

新增信用账户

信用账户允许透支(要支付利息),但应在信用额度内。每月1日结算利息,每年1月1日结算年费

系统设计

基类Account派生SavingAccount和CreditAccount两个子类。

基类Account中,保留数据成员:id账号,balance余额,total静态数据成员账户总金额,成员方法show输出信息。原来的record,error 方法的访问控制权限修改为 protected,供派生类调用,同时还有一个protected的构造方法。

处理存款deposit、处理取款withdraw、结算settle方法因具体处理方式不同,放置在派生类中。

增加Accumulator类实现各个账户的按日累加和的功能

系统实现

Accumulator类

public class Accumulator {
    private Date lastDate;	//上次变更数值的时期
    private double value;	//数值的当前值
    private double sum;		//数值按日累加之和

    //构造函数,date为开始累加的日期,value为初始值
    public Accumulator(final Date date, double value) {}

    //获得到日期date的累加结果
    public final double getSum(final Date date)  {}

    //在date将数值变更为value
    public void change(final Date date, double value) {}

    //初始化,将日期变为date,数值变为value,累加器清零
    public void reset(final Date date, double value) {}
}

Account类


public class Account {
    private String id;	//帐号
    private double balance;	//余额
    static double total=0; //所有账户的总金额

    //供派生类调用的构造函数,id为账户
    protected Account(final Date date, final String id){}
    //记录一笔帐,date为日期,amount为金额,desc为说明
    protected void record(final Date date, double amount, final String desc){}
    //报告错误信息
    protected final void error(final String msg) {}

    public final String getId()  { }
    public final double getBalance()  {  }
    public static double getTotal() { }
    //显示账户信息
    void show() {}
}

CreditAccount类

public class CreditAccount extends Account{
    private Accumulator acc;	//辅助计算利息的累加器
    private double credit;		//信用额度
    private double rate;		//欠款的日利率
    private double fee;			//信用卡年费

    private final double getDebt()  {}	//获得欠款额


    //构造函数
    public CreditAccount(final Date date, final String id, double credit, double rate, double fee){}
    public final double getCredit()  {  }
    public final double getRate()  {  }
    public final double getFee()  {  }
    public final double getAvailableCredit()  {}	//获得可用信用

    //存入现金
    public void deposit(final Date date, double amount, final String desc){}
    //取出现金
    public void withdraw(final Date date, double amount, final String desc){}
    //结算利息和年费,每月1日调用一次该函数
    public void settle(final Date date){}
    public final void show() {}
}

SavingsAccount类 

public class SavingsAccount extends Account{
    private Accumulator acc;	//辅助计算利息的累加器
    private double rate;		//存款的年利率

    //构造函数
    public SavingsAccount(final Date date, final String id, double rate){}
    public final double getRate()  { }
    //存入现金
    public void deposit(final Date date, double amount, final String desc) {}
    //取出现金
    public void withdraw(final Date date, double amount, final String desc) {}
    //结算利息,每年1月1日调用一次该函数
    public void settle(final Date date){}

}

系统测试

个人银行账户管理系统课程设计报告

体会心得

设计一个共同的父类 Account 类来派生出需要的两个子类,继承派生使得同类不同功能的实现更加的容易

利用super()对父类初始化

5.个人个人银行账户管理系统版本0.5(对应第8章记录)

系统需求

新增了输入功能,让用户选择实现存取等功能。

系统设计

添加switch选择语句,完成让用户选择功能

用Scanner实现数据类型的输入

Account变为抽象类,deposit、withdraw、settle为抽象方法。可以通过父类的引用来调用子类的方法。这样可以通过一个父类的数组来实现不同的账户的存储操作。

系统实现

Account类修改

abstract public class Account {
    //存入现金,date为日期,amount为金额,desc为款项说明
    abstract public  void deposit(final Date date, double amount, final String desc) ;
    //取出现金,date为日期,amount为金额,desc为款项说明
    abstract public  void withdraw(final Date date, double amount, final String desc) ;
    //结算(计算利息、年费等),每月结算一次,date为结算日期
    abstract public  void settle(final Date date) ;
    
}

CreditAccount类修改

public final void show() {
        super.show();
        System.out.println("\tAvailable credit:" + getAvailableCredit());
    }

 BANK类输入和switch语句

import java.util.Scanner;

public class BANK5 {
    public static void main(String[] args){
        char cmd;
        Scanner scanner=new Scanner(System.in);
        do {
            //显示日期和总金额
            date.show();
            System.out.println("\tTotal: "+Account.getTotal()+"\tcommand>");

            int index, day;
            double amount;
            String desc;

            cmd=scanner.next().charAt(0);
            switch (cmd) {
                case 'd':	//存入现金
                    index=scanner.nextInt();
                    amount=scanner.nextDouble();
                    desc=scanner.nextLine();
                    accounts[index].deposit(date, amount, desc);
                    break;
                case 'w':	//取出现金
                    index=scanner.nextInt();
                    amount=scanner.nextDouble();
                    desc=scanner.nextLine();
                    accounts[index].withdraw(date, amount, desc);
                    break;
                case 's':	//查询各账户信息
                    for (int i = 0; i < n; i++) {
                        System.out.print("[" + i + "] ");
                        accounts[i].show();
                        System.out.println();
                    }
                    break;
                case 'c':	//改变日期
                    day=scanner.nextInt();
                    if (day < date.getDay())
                        System.out.println("You cannot specify a previous day");
                    else if (day > date.getMaxDay())
                        System.out.println("Invalid day");
                    else
                        date =new Date(date.getYear(), date.getMonth(), day);
                    break;
                case 'n':	//进入下个月
                    if (date.getMonth() == 12)
                        date =new Date(date.getYear() + 1, 1, 1);
                    else
                        date =new Date(date.getYear(), date.getMonth() + 1, 1);
                    for (int i = 0; i < n; i++)
                        accounts[i].settle(date);
                    break;
            }
        } while (cmd != 'e');
        scanner.close();
    }
}

系统测试

个人银行账户管理系统课程设计报告

体会心得

Java中没有c++的运算符重载功能,需要通过具体方法来实现。

抽象类不能有对象但是可以声明引用其子类。

6.个人个人银行账户管理系统版本0.6(对应第9章记录)

系统需求

使得测试程序操作更便捷

系统设计

使用ArrayList创建账户数组,动态改变数组大小,添加新账户的功能。

系统实现

BANK类

import java.util.ArrayList;
public class BANK6 {
    public static void main(String[] args) {
        ArrayList<Account> accounts=new ArrayList<Account>();//创建账户数组,元素个数为0
    }
}

系统测试

个人银行账户管理系统课程设计报告

体会心得

学习了Java类库中的 ArrayList 实现了类的对象数组功能

一个共同的父类的对象数组可以统一管理其子类的对象

三、总结

最终功能:

1.一个简单的switch语句,供用户测试各个功能

2.一个日期累加器功能,记录日期的累加值

3.由Account类派生SavingsAccount和CreditAccount两个子类。第一个子类实现基本信息的存储、每月利息计算等功能,第二个子类实现扣除年费、信用卡透支等功能

Java中的输入问题,通过CSDN上各路大佬罗列的输入方法,选择了Scanner来实现不同数据的读入。

Java中没有C++的运算符重载功能,只能通过具体方法来实现。

C++中的floor在Java中需要通过Math.floor调用。

Arrylist声明的对象数组不必关心空间分配问题。

银行系统的六个版本,让我熟悉了Java的基本语法,也体会到了Java和C++的不同的程序设计思想。我也更加了解了面向对象的封装性、继承性、多态性。各种访问权限的定义,继承的使用,父类方法的覆写……

上一篇:leetcode322. 零钱兑换(完全背包)


下一篇:金额格式化