JAVA实验——更改C++中4到12章个人银行账户管理系统案例的心得体会(第6和7章)

3.第6章——增添字符串、对象数组

     改动的一些点:本章实例中增加了Date类,对照前两章做出java的一些基本类格式的改动即可。此外的改动有:

                     (1)java中字符串类型不需要像C++那样还要调用std::string,而直接使用默认包lang中String类。

                     (2)在使用Date对象引用作参数时,由于java没有引用类型的符号&,所以在作函数形参时直接使用Date对象。

                     (3)在创建Date对象时,java不能直接使用类名创建类的对象,而需要用Date date=new Date(int,int,int)才能声明并初始化一个Date对象,同样当需要创建一个Date对象作参数时也需要new一个Date对象。

                     (4)java里面对象数组有多种写法,其中的每一个对象也都需要和上面说的方法一样一个一个new。最简单的写法就是:SavingsAccount[]accounts={new SavingsAccount(date,String,double),new ......}

         (5)C++中的sizeof()函数用来计算对象所占内存空间大小,在java里没有。所以将n=sizeof(accounts)/sizeof(SavingsAccount)改成了accounts.length()。其中length()方法返回数组长度,实现的功能相同。

源代码:

Data类:public class Date {
private int year,month,day,totalDays;//该日期是从公元元年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){
this.year=year;
this.month=month;
this.day=day;
if(day<=0||day>getMaxDay()){
System.out.print("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++;
}
public final int getMaxDay() {
if(isLeapYear() && month==2) return 29;
else return DAYS_BEFORE_MONTH[month]-DAYS_BEFORE_MONTH[month-1];
}
public final void show() {
System.out.print(getYear()+"-"+getMonth()+"-"+getDay());
}
public final int getYear() {return year;}
public final int getMonth() {return month;}
public final int getDay() {return day;}
public final boolean isLeapYear() {
return year%4==0&&year%100!=0||year%400==0;
}
public final int distance(final Date date) {
return totalDays-date.totalDays;
}
}

SavingAccount6类:

public class SavingsAccount6 {

private static double total=0;
private String id;
private Date lastDate;//账号,上一次余额变动日期
private  double balance,rate,accumulation;//余额,年利率,余额按日累加值
public static double getTotal(){return total;}
public SavingsAccount6(final Date date,final String id,double rate){
lastDate=date;
this.id=id;
this.rate=rate;
balance=0;
accumulation=0;
date.show();
System.out.println("\t#"+id+" created");
}
private final void error(final String msg) {
System.out.println("Error(#"+id+"):"+msg);
}
//记录一笔账,有日期、金额和说明(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;//保留小数点后两位
total+=amount;
balance+=amount;
date.show();
System.out.println("\t#"+id+"\t"+amount+"\t"+balance+"\t"+desc);
}
//获得到指定日期为止的存款金额按日累积值
private final double accumulate(final Date date){
return accumulation+balance*date.distance(lastDate);
}
//存入和取出现金
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())
System.out.println("not enough money");
else
record(date,-amount,desc);
}
//显示账户信息
public void settle(final Date date){
Date date0=new Date(date.getYear()-1,1,1);
double interest=accumulate(date)*rate/date.distance(date0);//计算年息
if(interest!=0)
record(date,interest,"interest");
accumulation=0;
}
public final void show(){
System.out.print(id+"\tBalance: "+balance);
}
public final String getId(){return id;}
public final double getBalance(){return balance;}
public final double getRate(){return rate;}

}

SavingsAccount61类:

public class SavingsAccount61 {
public static void main(String args[]){
Date date=new Date(2008,11,1);
SavingsAccount6[] accounts={new SavingsAccount6(date,"03755217",0.015),new SavingsAccount6(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");
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:"+SavingsAccount6.getTotal());
}

}


4.第7章——继承与派生,抽象出父类,增添子类

    改动的一些点:从本章开始,多个类的继承派生关系使得类越来越多,也越来越复杂。

                      (1)java中类的继承用的是extends关键字,而非C++里的class SavingsAccount:public Account{};而且java没有C++里的继承类型。

                       (2)在C++中将原有的record和error成员函数访问控制权限修改为protected,而且设置了一个保护的构造函数供派生类调用,在java中不作改动,仍保留protected。

                         (3)由于两类账户计息对象和周期不同,但都需要将某个数值(余额或欠款金额)按日累加,所以选择建立新类Accumulator。同上一章类似,在调用Accumulator对象时注意使用new。

                      (4)由于子类2中的show()函数显示的与父类不尽相同,在调用父类show(),之后还要将额外的信息输出。

                      (5)对于继承自父类的构造方法或者方法中需要调用父类同名方法,java与C++很大的不同是引入了关键字super,并且在子类构造方法中需要首先用super(Date,String)去初始化继承自父类那部分的域变量。

                        注:此程序的不足之处在于,两个子类中的deposit、withdraw、settle方法是彼此独立的,只有明确知道一个对象的具体类型之后才能调用它的这些方法,这也是不能将main()方法中的3个账户放在一个对象数组中进行操作的内在原因。在下一章将通过C++中的虚函数来解决(而相应的,在java中也有机制实现)。

源代码:

Date类同上。

Accumulator类:

public class Accumulator { //将某个数值按日累加


        private Date lastDate; //上次变更数值的时期
private double value; //数值的当前值
private double sum; //数值按日累加之和
//构造函数,date为开始累加的日期,value为初始值
public Accumulator(final Date date, double value){
lastDate=date;
                this.value=value;
sum=0;
}
//获得到日期date的累加结果
public final double getSum(final Date date){return sum+value * date.distance(lastDate);
}
//在date将数值变更为value
public void change(final Date date, double value) {
sum = getSum(date);
lastDate = date;
this.value = value;
}
//初始化,将日期变为date,数值变为value,累加器清零
public void reset(final Date date, double value) {
lastDate = date;
this.value = value;
sum = 0;

}

}

Account类(父类):
public class SavingsAccount7 {
private String id;
private double balance;
private static double total=0;//所有账户的总金额
protected SavingsAccount7(final Date date,final String id){
this.id=id;
balance=0;
date.show();
System.out.println("\t#"+id+" created");
}
protected final void error(final String msg) {
System.out.println("Error(#"+id+"):"+msg);
}
//记录一笔账,有日期、金额和说明(desc)
protected void record(final Date date,double amount,final String desc){
amount=Math.floor(amount*100+0.5)/100;//保留小数点后两位
total+=amount;
balance+=amount;
date.show();
System.out.println("\t#"+id+"\t"+amount+"\t"+balance+"\t"+desc);
}
public void show(){
System.out.print(id+"\tBalance: "+balance);
}
public final String getId(){return id;}
public final double getBalance(){return balance;}
public static double getTotal(){return total;}

}

SavingsAccount类(子类1):

public class SavingsAccount71 extends SavingsAccount7{
private Accumulator acc;//辅助计算利息的累加器
private double rate;//存款的年利率
public SavingsAccount71(final Date date,final String id,double rate){
super(date,id);
this.rate=rate;
acc=new Accumulator(date,0);
}
public final double getRate(){return rate;}
//存入和取出现金
public void deposit(final Date date,double amount,final String desc){
record(date,amount,desc);
acc.change(date, getBalance());
}
public void withdraw(final Date date,double amount,final String desc){
if(amount>getBalance())
System.out.println("not enough money");
else{
record(date,-amount,desc);
acc.change(date, getBalance());
}
}
public void settle(final Date date){
double interest=acc.getSum(date)*rate/date.distance(new Date(date.getYear()-1,1,1));//计算年息
if(interest!=0)
record(date,interest,"interest");
acc.reset(date, getBalance());
}

}

CreditAccount类(子类2):

public class SavingsAccount72 extends SavingsAccount7{
private Accumulator acc;
private double credit;//信用额度
private double rate;//欠款的日利率
private double fee;//信用卡年费
private final double getDebt(){
double balance=getBalance();
return (balance<0?balance:0);
}
public SavingsAccount72(final Date date,final String id,double credit,double rate,double fee){
super(date,id);
this.credit=credit;
this.rate=rate;
this.fee=fee;
acc=new Accumulator(date,0);
}
public final double getCredit(){return credit;}
public final double getRate(){return rate;}
public final double getFee(){return fee;}
public final double getAvailableCredit(){//获得可用信用额度
if(getBalance()<0)
return credit+getBalance();
else
return credit;
}
public void deposit(final Date date,double amount,final String desc){
record(date,amount,desc);
acc.change(date, getDebt());
}
public void withdraw(final Date date,double amount,final String desc){
if(amount-getBalance()>credit)
System.out.println("not enough credit");
else{
record(date,-amount,desc);
acc.change(date, getDebt());
}
}
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());
}
public final void show(){
super.show();
System.out.print("\tAvailable credit: "+getAvailableCredit());
}
public static void main(String args[]){
Date date=new Date(2008,11,1);
SavingsAccount71 sa1=new SavingsAccount71(date,"S3755217",0.015);
SavingsAccount71 sa2=new SavingsAccount71(date,"02342342",0.015);
SavingsAccount72 ca=new SavingsAccount72(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:"+SavingsAccount7.getTotal());
}
}

猜你喜欢

转载自blog.csdn.net/qq_37155773/article/details/79853392