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

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

一、课程设计要求与目的

  1. 模仿个人银行账户管理系统的C++版本(第4章-第9章),使用Java语言重新实现该系统,比较C++与Java在实现上的异同,熟练掌握Java基础及语法。

  2. 根据业务需求的增加,对个人银行账户管理系统进行功能上的完善,利用面向对象的思想对代码进行重构,体会抽象、封装、继承、多态等特性在实际系统中的应用,掌握构造可复用、可扩展、可维护软件的基本技能。

二、课程设计版本记录

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

1.1 系统需求
  1. 创建银行账户,提示创建成功的信息,账户包括账号(id) 、 余额(balance) 、 年利率(rate) 等信息

  2. 对每一个账户有三个操作:存入现金(deposit),更新余额;取出现金(withdraw),更新余额;计算到指定时间的账户获得的年息(settle),更新余额

  3. 输出每一条操作的记录,格式为:日期(创建账户后的第几天)+账户+现金/年息+余额

  4. 最后输出账户总余额

1.2 系统设计
  1. 功能较为简单直接,可以直接设计一个 SavingsAccount 类,包括id、balance、rate等数据成员

  2. 设计私有成员record 方法实现存入和取出现金以及结算年息的功能,并更新余额及输出

  3. 因为余额的变化,所以使用日利率来计算年息,这时候需要私有变量lastDate、accumulation来记录余额变化的日期和余额累加值,再通过accumulate方法计算到指定日期时账户余额按日累加的值

  4. 时间的设计,为了便于表示,使用整型数据,记录相对于开户后的天数,两者相减即表示过了多少天

1.3 系统实现
  1. 类的成员变量和方法
public class SavingsAccount {
    private int id;				//账号
    private double balance;		//余额
    private double rate;		//存款的年利率
    private int lastDate;		//上次变更余额的时期
    private double accumulation;	//余额按日累加之和
    
    // 构造函数
    public SavingsAccount(int date, int id, double rate) {}
    // 获取私有成员的值
    public int getId() {}
    public double getBalance() {}
    public double getRate() {}

    //记录一笔帐,date为日期,amount为金额,desc为说明
    private void record(int date, double amount) {}
    //获得到指定日期为止的存款金额按日累积值
    private double accumulate(int date) {}
    //存入现金
    public void deposit(int date, double amount) {}
    //取出现金
    public void withdraw(int date, double amount) {}
    //结算利息,每年1月1日调用一次该函数
    public void settle(int date) {}

    //显示账户信息
    public void show() {}
}
  1. 通过构造函数创建账户,并输出创建成功提示语
// 构造函数
public SavingsAccount(int date, int id, double rate) {
	this.id = id;
	this.balance = 0;
	this.rate = rate;
	this.lastDate = date;
	this.accumulation = 0;
	System.out.println(date + "\t#" + id + " is created");
}
  1. 重点方法介绍

    • accumulate 方法,计算出到指定日期的金额累积值,便于处理操作后余额的更新变动
    //获得到指定日期为止的存款金额按日累积值
    private double accumulate(int date){
    	return accumulation + balance * (date - lastDate);
    }
    
    • settle 方法,计算年息,可以直接调用accumulate 方法,通过 余额按日累加之和/日利率 这一计算公式计算
    //结算利息,每年1月1日调用一次该函数
    public void settle(int date){
    	double interest = accumulate(date) * rate / 365;	//计算年息
    	if (interest != 0)
    		record(date, interest);
    	accumulation = 0;
    }
    
    • record 方法,按格式输出每一条记录,更新金额累加值,余额以及余额变动日期。floor方法用于向下取整,返回 double 类型
    //记录一笔帐,date为日期,amount为金额,desc为说明 
    private void record(int date, double amount){
    	accumulation = accumulate(date);
        lastDate = date;
       	amount = floor(amount * 100 + 0.5) / 100;	//保留小数点后两位
      	balance += amount;
        System.out.println(date + "\t#" + id + "\t" + amount + "\t" + balance);
    }
    
1.4 系统测试

在这里插入图片描述

说明

  1. 结果前两行表明在第一天创建两个账户成功,实现了创建账户功能

  2. 结果3-6行表明在不同的时间对两个账户进行存入和取出现金的操作,余额计算正确;结果7-8行计算出在第90天每个账户获得的年息,计算也正确,实现了三大操作

  3. 结果最后两行是账户总的信息显示

1.5 体会心得
  1. Java面向对象的语法更为严谨,实例化对象必须使用关键字new,单纯的SavingsAccount sa0只是对象引用的声明
  2. 使用floor方法,必须引入java.lang.Math.floor的包
  3. 在面向对象思想的简单应用上,Java和c++语法上没有很大的不同

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

2.1 系统需求
  1. 新增:计算出所有账户的总金额并输出
2.2 系统设计
  1. 在类的私有成员变量里增加一个double类型的total变量。
private static double total = 0; //所有账户的总金额
  • 设计说明:因为是为了记录所有账户的总金额,属于整个类的一个属性,即应为static
  1. total 作为静态属性,使用静态方法获取值
public static double getTotal() {
	return total;
}
2.3 系统实现
  1. 处理记录的时候,更新账户总金额
private void record(int date, double amount){
	accumulation = accumulate(date);
	lastDate = date;
	amount = floor(amount * 100 + 0.5) / 100;	//保留小数点后两位
	balance += amount;
	total += amount; // 账户总金额更新
	System.out.println(date + "\t#" + id + "\t" + amount + "\t" + balance);
}
  1. 获取total值的静态方法由类调用
System.out.println("Total: " + SavingsAccount2.getTotal());
2.4 系统测试

在这里插入图片描述

说明

  1. 最后total值为两个账户余额之和
2.5 体会心得
  1. 静态变量适合用作对一个整体的求和计算
  2. 静态数据成员必须由静态成员方法来访问
  3. static的使用,Java和c++类似

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

3.1 系统需求
  1. 修改:日期以年月日格式显示,账号改为字符串数据类型

  2. 新增:三大操作有对应的字符串描述

  3. 修改:使用数组创建账户,简化测试代码

  4. 新增:提供一个报错函数反映错误信息

3.2 系统设计
  1. 增添Date 日期类,包括年、月、日等数据成员,通过isLeapYear方法判断是否为闰年,distance方法获取日期间的天数,这里要考虑不同月的天数问题和闰年的情况,show方法显示日期的功能
public class Date{ //日期类
    private int year;          //年
    private int month;         //月
    private int day;           //日
    private int totalDays = 0; //该日期是从公元元年1月1日开始的第几天
    private final int[] DAYS_BEFORE_MONTH = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };

    //用年、月、日构造日期
    public Date(int year,int month,int day) {}

    //判断当年是否为闰年
    public boolean isLeapYear() {}
    //获得当月有多少天
    public final int getMaxDay() {}
    //获取年月日的值
    public int getYear() {}
    public int getMonth() {}
    public int getDay() {}

    //计算两个日期之间差多少天
    public int distance(Date date) {}
    //输出当前日期
    public final void show() {}
}
  1. 修改:在 SavingsAccount 类中使用Date类作为数据成员,并使用Date类方法,在SavingsAccount 类操作方法中添加 decs 字符串参数
private Date lastDate;		//上次变更余额的时期

//记录一笔帐,date为日期,amount为金额,desc为说明
private void record(final Date date, double amount, final String desc) {}
//存入现金
public void deposit(final Date date, double amount, final String desc) {}
//取出现金
public void withdraw(final Date date, double amount, final String desc) {}
3.3 系统实现
  1. Date类的重要方法

    • Date 构造函数,创建日期的同时,增加一个totalDays的数据变量计算出此日距离公元元年1月1日的天数
    //用年、月、日构造日期
    public Date(int year,int month,int day){
    	this.year = year;
    	this.month = month;
    	this.day = day;
    
    	if (day <= 0 || day > getMaxDay()) {
    		System.out.println("Invalid date: ");
    		show();
    		System.out.println();
    		System.exit(1);
    	}
    	int years = year - 1;
    	totalDays = years * 365 + years / 4 - years / 100 + years / 400
                    + DAYS_BEFORE_MONTH[month - 1] + day; // 天数的计算
    	if (isLeapYear() && month > 2) totalDays++; // 闰年的特殊情况
    }
    
    • getMaxDay 方法,获取当月天数,针对闰年特判
    //获得当月有多少天
    public final int getMaxDay(){
       	if (isLeapYear() && month == 2){
            return 29;
       	} else{
        	return DAYS_BEFORE_MONTH[month]- DAYS_BEFORE_MONTH[month - 1];
    	}
    }
    
    • distance 方法,计算日期差,便于 SavingsAccount 类方法直接调用
    //计算两个日期之间差多少天
    public int distance(Date date){
    	return totalDays - date.totalDays;
    }
    
  2. SavingsAccount 类重要方法修改

    • record 方法,调用日期显示函数,格式化输出,增添字符串描述
    //记录一笔帐,date为日期,amount为金额,desc为说明
    private void record(final Date date, double amount, final String desc){
    	accumulation = accumulate(date);
        lastDate = date;
        amount = floor(amount * 100 + 0.5) / 100;	//保留小数点后两位
        balance += amount;
        total += amount;
        date.show();
        System.out.println("\t#" + id + "\t" + amount + "\t" + balance + "\t" + desc);
    }
    
    • settle 方法,使用 distance 方法计算前一年到指定日期过了多少天
    //结算利息
    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;
    }
    
    • error 方法,错误情况处理
    //报告错误信息
    private final void error(final String msg){
        System.out.println("Error(#" + id + "): " + msg);
    }
    
3.4 系统测试

​ 测试样例:运用数组的循环遍历,减少了代码的冗余

public static void main(String[] args){
	Date date = new Date(2008, 11, 1);

   	//建立几个账户
    SavingsAccount3[] accounts = {
    	new SavingsAccount3(date, "S3755217", 0.015),
    	new SavingsAccount3(date, "02342342", 0.015)
    };
    final int n = accounts.length; //账户总数
    //11月份的几笔账目
    accounts[0].deposit(new Date(2008,11,5), 5000, "salary");
    accounts[1].deposit(new Date(2008,11,25), 10000, "sell stock 0323");
    //12月份的几笔账目
    accounts[0].deposit(new Date(2008,12,5), 5500, "salary");
    accounts[1].withdraw(new Date(2008,12,20), 4000, "buy a laptop");
    accounts[1].withdraw(new Date(2008,12,22), 10000000, "buy a car");

    //结算所有账户并输出各个账户信息
    System.out.println();
    for (int i = 0; i < n; i++) {
		accounts[i].settle(new Date(2009, 1, 1));
		accounts[i].show();
		System.out.println();
    }
    System.out.println("Total: " + SavingsAccount3.getTotal());
}

​ 运行结果:
在这里插入图片描述

说明

  1. 创建2018-11-1这一日期作为初始日期
  2. 结果前两行表明在2008-11-1两个账户创建成功
  3. 结果3-6行表明在不同的时间对两个账户进行存入和取出现金的操作,有了相关字符串描述;结果9-13行计算出在2019-1-1这一天每个账户获得的年息,并输出了账户总信息和所有账户总金额
  4. 第8行通过error方法显示出一条错误信息
3.5 体会心得
  1. 要时刻具有封装的思想,关于日期的一些计算完全可以抽象出一个类进行实现,使代码显得更为简洁明了
  2. 通过类的组合,使代码间相互独立,但类与类之间又可以互相调用实现更多功能
  3. 对一些重复度极高的代码要有简化的思想,样例最后通过对象数组的循环极大减少了重复的代码,显得美观简洁

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

4.1 系统需求
  1. 新增:创建信用账户,实现根据信用额度透支、拥有欠款利息、扣除信用卡年费等功能

  2. 修改:封装计算日期差和实现金额按日累加的方法

4.2 系统设计
  1. 增加 CreditAccount类,包括信用额度(credit)、欠款日利率(rate)、信用卡年费(fee)等数据成员,以及自身存入(deposit)和取出现金(withdraw)、结算年息年费(settle)、显示信息(show)的方法
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(){}
}

  1. 抽象出Account类,包括id、balance、total等账户公有的数据成员,以及 record、error、show等共同方法,以此派生出CreditAccount类、SavingsAccount类
public class Account{ //账户类
    private String id; // 帐号
    private double balance; // 余额
    private static double total; // 所有账户的总金额

    // 供派生类调用的构造函数,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() {}
    // 显示账户信息
    public void show()
}
  • 设计说明:因为Account作为父类,其方法需被派生类继承使用,所以应该使用protected

​ 3. 增加 Accumulator 类,作为其他类的利息累加器,包括lastDate 、 value 、 sum,设计方法计算累加之和和更新当前数据

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) {}
}
4.3 系统实现
  1. Accumulator 类的重要方法

    • change 方法,用于更新数据
    //用date将数值变更为value
    public void change(final Date date, double value) {
        sum = getSum(date);
        lastDate = date;
        this.value = value;
    }
    
    • getSum 方法,类似于之前版本的accumulate方法,计算金额按日累加之和,
    //获得到日期date的累加结果
    public final double getSum(final Date date){
            return sum + value * date.distance(lastDate);
    }
    
  2. CreditAccount 类的重要方法

    • getDebt 方法和 getAvailableCredit 方法。调用getBalance 父类方法获得余额值,余额为负则为欠款额,同时信用额度减去相应余额数
    //获得欠款额
    private final double getDebt(){
    	double balance = getBalance();
    	return (balance < 0 ? balance : 0);
    }
    //获得可用信用
    public final double getAvailableCredit(){
    	if (getBalance() < 0){
    		return credit + getBalance();
    	} else{
    		return credit;
    	}
    }
    
    • settle 方法,除了通过调用acc 这一累加器计算年息,还在每年1月扣除的信用卡年费
    //结算利息和年费,每月1日调用一次该函数
    public void settle(final Date date){
    	double interest = acc.getSum(date) * rate;
    	if (interest != 0)
    		record(date, interest, "interest");
    	if (date.getMonth() == 1)
    		record(date, -fee, "annual fee");
    	acc.reset(date, getDebt());
    }
    
    • withdraw 方法,根据信用账户自身特点进行修改,当所取金额与余额的差值高于信用额度时无法借款,抛出错误信息(父类方法)
    //取出现金
    public void withdraw(final Date date, double amount, final String desc){
    	if (amount - getBalance() > credit) {
    		error("not enough credit");
    	} else {
    		record(date, -amount, desc);
    		acc.change(date, getDebt());
    	}
    }
    
4.4 系统测试

​ 测试样例:

public static void main(String[] args){
	Date date = new Date(2008, 11, 1);

	//建立几个账户
	SavingsAccount4 sa1 = new SavingsAccount4(date, "S3755217", 0.015);
	SavingsAccount4 sa2 = new SavingsAccount4(date, "02342342", 0.015);
	CreditAccount ca = new CreditAccount(date, "C5392394", 10000, 0.0005, 50);
	//11月份的几笔账目
	sa1.deposit(new Date(2008, 11, 5), 5000, "salary");
	ca.withdraw(new Date(2008, 11, 15), 2000, "buy a cell");
	sa2.deposit(new Date(2008, 11, 25), 10000, "sell stock 0323");
	//结算信用卡
	ca.settle(new Date(2008, 12, 1));
	//12月份的几笔账目
	ca.deposit(new Date(2008, 12, 1), 2016, "repay the credit");
	sa1.deposit(new Date(2008, 12, 5), 5500, "salary");
	//结算所有账户
	sa1.settle(new Date(2009, 1, 1));
	sa2.settle(new Date(2009, 1, 1));
	ca.settle(new Date(2009, 1, 1));
	//输出各个账户信息
	System.out.println();
	sa1.show();
    System.out.println();
    sa2.show(); 
    System.out.println();
    ca.show();
    System.out.println();
    System.out.println("Total: " + Account.getTotal());
}

​ 运行结果:

在这里插入图片描述

说明

  1. 只看信用账户,先借款2000,后有欠款年息16.0,之后存入现金还清欠款,最后12-1扣除年费,导致信用额度减少50,实现了新增功能
  2. 储蓄账户结果与之前版本相同,正确
4.5 体会心得
  1. 需要适当的总结类与类之间的共同点,抽象出父类,简化代码,使类与类之间逻辑上的关联更为紧密
  2. Java的继承与c++较为类似,但注意使用extends关键字;构造函数上有很大的区别,必须有super方法的调用(隐式或显示)
  3. 使用继承的时候,需要明确数据成员的访问权限,善于使用protected
  4. 对一些重要功能可以尝试封装成类,以便代码复用,这样有利于类与类在功能上实现独立,以此减小维护的难度

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

5.1 系统需求
  1. 修改:用户输入自行选择操作功能

  2. 修改:完善父类和派生类间的关系,应用抽象类的知识

5.2 系统设计
  1. 父类Account定义为抽象类,共同方法deposit、withdraw、settle定义为抽象方法,这样不仅子类可以有自己的实现方法,还可以通过父类的引用调用这些方法

  2. 通过Java输入语句判断用户选择的操作,分别调用不同的方法

5.3 系统实现
  1. Account使用抽象方法,变为抽象类
public abstract class Account2{}

//存入现金,date为日期,amount为金额,desc为款项说明
public abstract void deposit(final Date date, double amount, final String desc);
//取出现金,date为日期,amount为金额,desc为款项说明
public abstract void withdraw(final Date date, double amount, final String desc);
//结算(计算利息、年费等),每月结算一次,date为结算日期
public abstract void settle(final Date date);
  1. Java输入语句语法,引用Scanner包创建一个输入实例,调用内置方法进行输入

    • 输入单个字符,charAt(0)取字符串第一个字符
    import java.util.Scanner;
    
    Scanner s = new Scanner(System.in);
    String str = s.next();
    cmd = str.charAt(0);
    
    • 输入数值和字符串
    int index;
    double amount;
    String desc;
    
    index = s.nextInt();
    amount = s.nextDouble();
    desc = s.nextLine();
    
  2. 指令功能的实现

    • 输入c指令改变当前日期,通过调用Date的方法实现
    case 'c':	//改变日期
    	day = s.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;
    
    • 输入n进入下个月,注意年息和年费的结算
    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;
    
5.4 系统测试

​ 测试样例和运行结果
在这里插入图片描述
在这里插入图片描述

说明

  1. 程序先创建一个日期,作为初始日期,并创建两个储蓄账户一个信用账户

  2. 显示功能菜单,列出具体操作所对应的字符指令

  3. 用户每次输入前都会提示账户的总金额

  4. 输入:c 5,即进入这个月5号

  5. 接下来对各个账户在不同时间进行存入、取出现金、结算年息等操作

  6. 第二次输入n,时间变为1月1日,需要结算年息和年费

  7. 输入s,显示所有账户的信息

  8. 输入 e , 此时退出测试程序

  9. 对比之前几个版本的测试样例,结果均正确

5.5 体会心得
  1. 一个系统的开发重点应当在于用户的使用,功能的选择极大体现了系统的灵活性,增加了用户的体验感
  2. 使用抽象类思想结合多态覆写的方法,使最后调用方法实现各项功能时更加简单易懂,也更为灵活
  3. c++中有运算符的重载,但Java舍弃了这一点,直接设计一个相关方法调用即可
  4. Java的输入语法相对于c++来说显得复杂一点,尤其是单个字符的输入,需要有取第一个字符的操作,但它体现的仍是一种面向对象的思想,使用Scanner这个类实现

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

6.1 系统需求
  1. 修改:测试样例中使用Java的容器代替数组,动态存储账户,并提高操作效率
6.2 系统设计
  1. 引入ArrayList包,通过容器创建数组
import java.util.ArrayList;

ArrayList<Account2> accounts = new ArrayList<Account2>();
6.3 系统实现
  1. 创建账户,增加一个type变量区分是储蓄账户还是信用账户,分别创建相应类实例,增添新账户使用容器内置add方法
case 'a':    //增加账户
	String t = s.next();
	type = t.charAt(0);
	id = s.next();
	if (type == 's') {
        rate = s.nextDouble();
        account = new SavingsAccount4(date, id, rate);
	} else {
        credit = s.nextDouble();rate = s.nextDouble();
        fee = s.nextDouble();
        account = new CreditAccount(date, id, credit, rate, fee);
	}
	accounts.add(account);
	break;
  1. 数组容器调用内部元素的方法,需要使用 .get(i). 类似于:
accounts.get(index).deposit(date, amount, desc);
  1. 程序结束后,需要清空容器,用内置remove方法
for (int i = 0; i < accounts.size(); i++){
	accounts.remove(i);
}
6.4 系统测试

​ 样例测试和运行结果

在这里插入图片描述

说明

  1. 菜单增加了创建账户功能

  2. 输入a指令,创建账户成功

  3. 后续功能一致,对比之前版本测试结果也均正确

6.5 体会心得
  1. 善于使用Java封装好的容器,通过调用其内置方法,可以带来极大的便利

三、课程设计总结

对所做工作的总体总结:总结该系统实现了哪些功能。在版本的演化中系统使用了面向对象思想的哪些特性来实现复用和扩展,可以结合Java为实现面向对象思想提供了哪些机制来谈论。课程设计过程中遇到的问题及问题的解决与收获。

功能实现

  1. 基类 Account :

    • 封装了账户的基本信息,账号、余额等
    • 设计出账户的一些公有方法,实现对每条账单的记录以及账户信息显示、总金额之和
  2. SavingsAccount 类:

    • 自己相关账户的创建和信息的存储

    • 实现自身的存入和取出现金的功能

    • 根据日期之差计算出账户所获年息

  3. CreditAccount 类:

    • 自己相关账户的创建和信息的存储
    • 实现自身的存入、取出现金或根据信用额度是否可以透支的功能
    • 根据时间计算欠款利息和是否扣除年费的功能
  4. Date 类:

    • 可以创建不同日期
    • 调用方法可以修改当前日期和进入下一个月
    • 计算出日期间所差天数
  5. Accumulator 类:

    • 累加器,适用于银行系统计算利息的类
    • 计算出账户余额按日累加之和

面向对象思想

  1. 封装

    对系统中一些重要的功能,如日期、账户、累加器等,都用单独的类进行了封装,由此实现功能间的独立,有利于后期的维护和更进一步的开发;同时通过对访问权限的设计不仅保护了数据成员,还保证了类与类之间的组合安全使用,以实现更多强大的功能

  2. 继承

    由 Account 作为父类派生出 SavingsAccount 类和 CreditAccount 类,在逻辑上符合现实意义,体现类与类之间的紧密关系,同时共同数据成员在父类中声明也简化了代码,结构清晰明了

  3. 组合

    不同于继承,组合间的类没有很大逻辑上的关联,但通过类的组合,可以完成很多强大的功能,比如在两类账户中通过与日期、累加器的组合实现了最基本的年息计算

  4. 多态

    虽说 Account 父类已经有了所有账户的共同方法,但不同的账户有不同的需求,多态的方法重写能够帮助子类账户更好的实现其需求,也使系统更加的完善、严谨

问题及解决

  1. 数据输入

    • 一开始并不清楚Java的输入语法,通过查阅博客后得知可以使用Scanner实例化一个输入对象进行操作
    • 对于单个字符的输入,需要调用charAt()方法,传入参数0,取第一个字符
  2. 运算符重载

    • 在Date类中,c++代码在计算日期之差时对减号进行了运算符重载,查阅资料后发现Java不支持运算符重载,于是直接写operator方法实现减号重载功能
  3. 项目包

    • 项目初期是直接将所有类放在一个文件中,显得代码冗长且结构不清晰,之后进行改进,将每个类都单独放在Java的项目包package
    • 在改进的过程中,曾遇到以下报错。因为Date的构造函数未设置访问权限,即为包的默认访问权限,所以在com.run这个外部包中无法访问,设置为public即可
    java: Date(int,int,int)在com.resource.Date中不是公共的; 无法从外部程序包中对其进行访问
    
  4. Java容器

    • 第6个版本目的在于用容器替代数组,一开始完全没有容器的概念,查阅资料后明白Java已经封装好了很多容器用于存储数据和对象,容器也有自身写好的方法以此来简便操作和提高效率

    • ArrayList是在这个系统中最适合于替代数组的一个容器

收获

通过此次实验,不仅更加直观的展现出c++和Java这两门语言的相似与不同之处,同时还让我体会到Java确实是一门面向对象的语言,在它的机制中面向对象这一思想体现的淋漓尽致。

6个版本的逐步改进,让我更加熟悉了Java的基本语法,也在报错和查阅资料的过程中掌握了很多之前被忽视掉的小细节,如访问权限,和一些书上没有涉及到的知识,像输入语法、数组容器等,这一次的实践练习是Java学习过程中必不可缺的一环。
系统更加的完善、严谨

问题及解决

  1. 数据输入

    • 一开始并不清楚Java的输入语法,通过查阅博客后得知可以使用Scanner实例化一个输入对象进行操作
    • 对于单个字符的输入,需要调用charAt()方法,传入参数0,取第一个字符
  2. 运算符重载

    • 在Date类中,c++代码在计算日期之差时对减号进行了运算符重载,查阅资料后发现Java不支持运算符重载,于是直接写operator方法实现减号重载功能
  3. 项目包

    • 项目初期是直接将所有类放在一个文件中,显得代码冗长且结构不清晰,之后进行改进,将每个类都单独放在Java的项目包package
    • 在改进的过程中,曾遇到以下报错。因为Date的构造函数未设置访问权限,即为包的默认访问权限,所以在com.run这个外部包中无法访问,设置为public即可
    java: Date(int,int,int)在com.resource.Date中不是公共的; 无法从外部程序包中对其进行访问
    
  4. Java容器

    • 第6个版本目的在于用容器替代数组,一开始完全没有容器的概念,查阅资料后明白Java已经封装好了很多容器用于存储数据和对象,容器也有自身写好的方法以此来简便操作和提高效率

    • ArrayList是在这个系统中最适合于替代数组的一个容器

收获

通过此次实验,不仅更加直观的展现出c++和Java这两门语言的相似与不同之处,同时还让我体会到Java确实是一门面向对象的语言,在它的机制中面向对象这一思想体现的淋漓尽致。

6个版本的逐步改进,让我更加熟悉了Java的基本语法,也在报错和查阅资料的过程中掌握了很多之前被忽视掉的小细节,如访问权限,和一些书上没有涉及到的知识,像输入语法、数组容器等,这一次的实践练习是Java学习过程中必不可缺的一环。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值