银行账户管理系统
- 1. 代码编写过程说明
- 2. 实现中发现的问题
- C++中cosnt与Java中final的比较:
- C++中 虚函数与纯虚函数的区别 以及在Java中对应的思想与实现:
- 3.代码展示
1. 代码编写过程说明
- chapter4:使用基本面向对象思想实现简单功能,引入Account类;
- chapter5: 在类中增添了静态属性与静态方法;
- chapter6:增添字符串作为域变量,main方法中使用对象数组存储账户,引入Data类管理时间,与Account进行组合;
- chapter7:使用了类的继承与派生,优化了类结构,父类为Account,子类为CreditAccount,引入Accumulate类,与Account类及其子类进行组合;
- chapter8:运用了多态属性,将Account设为抽象类,CreditAccount为其实现类;
- chapter9:使用ArrayList作为容器。
2. 实现中发现的问题
C++中cosnt与Java中final的比较:
- C++中:
-
const
用于基本数据类型前修饰常量,其值不能更改; -
const A *p = &a
表示其指向对象的内容不改变; -
A cosnt *p = &a
表示其指向不能改变,即指针的值不能改变; -
const
修饰函数表示该函数为常成员函数,只能读取类中数据成员,不能修改; -
public methodA(const classA *p){ }
防止参数指针指向被修改; -
public methodA(const int a){ }
在程序中不能修改a的值。
- Java中:
-
final
用于基本数据类型前,为常量标识符; -
final
用于对象引用前,修饰常引用,其绑定对象不能改变为其他对象; -
final
用于类前修饰最终类,表示其不能有派生类; -
final
用于方法前修饰最终方法,表示其方法不能被其派生类覆盖,当可以在本类中重载; -
final
用在参数列表中不能表示其值不能修改的语义,要想达到此目的则在方法内部加入限制性操作语句。
C++中 虚函数与纯虚函数的区别 以及在Java中对应的思想与实现:
- C++中,虚函数是实现多态的重要工具,对应java中的普通函数。
#include<iostream>
using namespace std;
class A
{
public:
void print()
{ cout<<"This is A"<<endl; }
};
class B : public A
{
public:
void print()
{ cout<<"This is B"<<endl; }
};
int mian(){
A a;
B b;
A *p1 = &a;
A *p2 = &b;
p1->print();
p2->print();
return 0;
}
输出结果都为“This is A”
#include<iostream>
using namespace std;
class A
{
public:
virtual void print(){cout<<"This is A"<<endl;}
};
class B : public A
{
public:
void print(){cout<<"This is B"<<endl;}
};
int main(){
A a;
B b;
A *p1 = &a;
A *p2 = &b;
p1->print();
p2->print();
return 0;
}
分别输出“This is A”和“This is B”
通过使用
Virtual
定义虚函数,使基类的对象指针可以通过统一的接口访问到基类及其派生类的同名函数。
class AClass {
public void Print() {
System.out.println("this is A");
}
}
class BClass extends AClass {
public void Print() {
System.out.println("this is B");
}
}
public class TestA {
public static void main(String[] args) {
AClass a = new AClass();
BClass b = new BClass();
AClass pa = a;
AClass pb = b;
a.Print();
b.Print();
}
}
分别输出“this is A”和“this is B”
在Java中,直接使用普通方法和基类引用即可访问到父类和其派生类的同名方法。
- C++中的纯虚函数也是其实现多态的重要方式,对应着Java中的抽象方法。
C++中纯虚函数是只有声名没有实现的方法,其实现在其子类中。含有纯虚函数的类为抽象类
virtual void deposit(const Date &date, double amount, const std::string &desc) = 0;
//取出现金,date为日期,amount为金额,desc为款项说明
virtual void withdraw(const Date &date, double amount, const std::string &desc) = 0;
//结算(计算利息、年费等),每月结算一次,date为结算日期
virtual void settle(const Date &date) = 0;
//显示账户信息
以上在Java中对应为:
abstract public void deposit(Data data,double amount,String desc);
abstract public void withdraw(Data data,double amount,String desc);
abstract public void settle(Data data);
Java中,抽象方法只有声名没有实现,用关键词
abstract
修饰,含有抽象方法的类为抽象类,也用abstract
修饰。其子类必须实现其方法。
3.代码展示
main方法
package chapter9;
import java.util.ArrayList;
import java.util.Scanner;
public class BankManageSystem {
public static void main(String[] args) {
Data data = new Data(2008,11,1);
ArrayList<Account> account = new ArrayList<>();
System.out.println("MENU\n"+
"(a)add account \n"+
"(d)deposit \n" +
"(w)withdraw \n" +
"(s)show \n" +
"(c)change day \n" +
"(n)next month \n" +
"(e)exit");
char cmd;
Scanner scanner = new Scanner(System.in);
do {
data.show();
System.out.print("\tTotal: "+Account.getTotal()+"\tcommand> ");
char type;
int index,day;
double amount,credit,rate,fee;
String decs,id;
cmd = scanner.next().charAt(0);
switch (cmd) {
case 'a':
Scanner sc = new Scanner(System.in);
System.out.print("type> ");
type = scanner.next().charAt(0);
System.out.println(type);
System.out.print("ID> ");
id = sc.nextLine();
System.out.print("*"+id+"* ");
if(type == 's') {
System.out.print("rate> ");
rate = scanner.nextDouble();
account.add(new SavingAccount(data,id,rate));
} else {
System.out.print("credit rate fee> ");
credit = scanner.nextDouble();
rate = scanner.nextDouble();
fee = scanner.nextDouble();
account.add(new CreditAccount(data,id,credit,rate,fee));
}
break;
case 'd':
System.out.print("index> ");
index = scanner.nextInt();
System.out.print("amount> ");
amount = scanner.nextInt();
System.out.print("desc> ");
decs = scanner.nextLine();
account.get(index).deposit(data,amount,decs);
break;
case 'w':
System.out.print("index amount> ");
index = scanner.nextInt();
amount = scanner.nextInt();
System.out.print("desc> ");
decs = scanner.nextLine();
account.get(index).withdraw(data,amount,decs);
break;
case 's':
for(int i = 0; i<account.size(); i++) {
System.out.print("["+i+"]");
account.get(i).show();
}
break;
case 'c':
day = scanner.nextInt();
if(day > data.getDay()) {
System.out.print("You cannot specify a previous day");
} else if(day > data.getMaxDay()) {
System.out.print("Invalid day");
} else {
data = new Data(data.getYear(),data.getMonth(),day);
}
break;
case 'n':
if(data.getMonth() == 12) {
data = new Data(data.getYear()+1,1,1);
} else {
data = new Data(data.getYear(), data.getMonth()+1, 1 );
}
for (Account value : account) {
value.settle(data);
}
break;
default:
break;
}
} while (cmd != 'e');
}
}
主体类
----------------------ACCOUNT----------------------------
abstract public class Account {
private String id;
private double balance;
static private double total = 0;
protected Account(Data data,String id) {
this.id = id;
balance = 0;
data.show();
System.out.println("\t#"+id+" created");
}
protected void record(Data data,double amount,String desc) {
amount = Math.floor(amount*100 + 0.5)/100;
balance += amount;
data.show();
System.out.println("\t#"+id+"\t"+amount+"\t"+balance+"\t"+desc);
}
protected void error(String msg) {
System.out.println("ERROR(#"+id+"): "+msg);
}
public String getId() {
return id;
}
public double getBalance() {
return balance;
}
public static double getTotal() {
return total;
}
public void show(){
System.out.println(id+"\tBalance: "+balance);
}
abstract public void deposit(Data data,double amount,String desc);
abstract public void withdraw(Data data,double amount,String desc);
abstract public void settle(Data data);
}
---------------------CREDITACCOUNT-----------------------------
public class CreditAccount extends Account{
private Accumulator acc;
private double credit;
private double rate;
private double fee;
public CreditAccount(Data data,String id,double credit,double rate,double fee) {
super(data,id);
this.credit = credit;
this.rate = rate;
this.fee = fee;
acc = new Accumulator(data,0);
}
private double getDebt() {
double balance = getBalance();
return (balance<0 ? balance : 0);
}
public double getCredit() {
return credit;
}
public double getRate() {
return rate;
}
public double getFee() {
return fee;
}
public double getAvailableCredit() {
if(getBalance() < 0) {
return credit + getBalance();
} else {
return credit;
}
}
public void deposit(Data data,double amount,String desc) {
record(data,amount,desc);
acc.change(data,getDebt());
}
public void withdraw(Data data,double amount,String desc) {
if(amount - getBalance() > credit) {
error("not enough credit");
} else {
record(data,-amount,desc);
acc.change(data,getDebt());
}
}
public void settle(Data data) {
double interest = acc.getSum(data)*rate;
if(interest != 0) {
record(data,interest,"interest");
}
if(data.getMonth() == 1) {
record(data,-fee,"annual fee");
}
acc.reset(data,getDebt());
}
public void show() {
super.show();
System.out.println("\tAvailable credit:"+getAvailableCredit());
}
}
----------------------SAVINGACCOUNT----------------------------
public class SavingAccount extends Account {
private Accumulator acc;
private double rate;
public SavingAccount(Data data,String id,double rate) {
super(data, id);
this.rate = rate;
acc = new Accumulator(data,0);
}
public double getRate(){
return rate;
}
public void deposit(Data data,double amount,String desc) {
record(data,amount,desc);
acc.change(data,getBalance());
}
public void withdraw(Data data,double amount,String desc) {
if (amount > getBalance()) {
error("not enough money");
} else {
record(data,-amount,desc);
acc.change(data,getBalance());
}
}
public void settle(Data data) {
if(data.getMonth() == 1) {
double interest = (acc.getSum(data)*rate)/
(data.minus(new Data(data.getYear()-1,1,1)));
if(interest != 0) {
record(data,interest,"interest");
}
acc.reset(data,getBalance());
}
}
}
封装的其他类
----------------------DATA-------------------------
public class Data {
private int year;
private int month;
private int day;
private int totalDays = 0;
final private int[] DAYS_BEFORE_MONTH;
Data(int year, int month, int day){
this.year = year;
this.month = month;
this.day = day;
DAYS_BEFORE_MONTH = new int[] { 0, 31, 59, 90, 120, 151,
181, 212, 243, 273, 304, 334, 365 };
if(day <= 0 || day > getMaxDay()) {
System.out.print("Invalid data:");
show();
System.exit(1);
}
int years = year - 1;
totalDays = year*365 + years/4 - years/100 + years/400
+ DAYS_BEFORE_MONTH[month - 1] + day;
if (isLeapYear() && month > 2){
totalDays++;
}
}
/**
* 判断是否为润年
* @return 是否为润年
*/
private boolean isLeapYear(){
return year%4==0 && year%100!=0 || year%400==0 ;
}
public int getYear(){
return year;
}
public int getDay() {
return day;
}
public int getMonth() {
return month;
}
public int getMaxDay(){
if( isLeapYear() && month==2 ){
return 29;
} else {
return DAYS_BEFORE_MONTH[month] - DAYS_BEFORE_MONTH[month-1];
}
}
/**
* 计算储蓄的时长
* @param d 结算开始日期
* @return 时长
*/
public int minus(Data d){
return this.totalDays - d.totalDays;
}
public void show(){
System.out.println(getYear()+" - "+getMonth()+"-"+getMonth());
}
}
----------------ACCUMULATOR----------------------
public class Accumulator {
private Data lastData;
private double value;
private double sum;
public Accumulator(Data data,double value) {
lastData = data;
this.value = value;
sum = 0;
}
public double getSum(Data data) {
return sum + value*(data.minus(lastData));
}
public void change(Data data,double value) {
sum = getSum(data);
lastData = data;
this.value = value;
}
public void reset(Data data,double value) {
lastData = data;
this.value = value;
sum = 0;
}
}