Java实验一
1.第四章:类
class SavingsAccount4 {
private int id;
private double balance;
private double rate;
private int lastDate;
private double accumulation;
private 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) ;
}
private double accumulate ( int date) {
return accumulation + balance * ( date - lastDate) ;
}
public SavingsAccount4 ( 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" ) ;
}
public int getId ( ) { return id; }
public double getBalance ( ) { return balance; }
public double getRate ( ) { return rate; }
public void deposit ( int date, double amount) {
record ( date, amount) ;
}
public void withdraw ( int date, double amount) {
if ( amount > getBalance ( ) )
System. out. println ( "Error: not enough money" ) ;
else
record ( date, - amount) ;
}
public void settle ( int date) {
double interest = accumulate ( date) * rate / 365 ;
if ( interest != 0 )
record ( date, interest) ;
accumulation = 0 ;
}
public void show ( ) {
System. out. println ( "#" + id + "\tBalance: " + balance) ;
}
public static void main ( String[ ] args) {
SavingsAccount4 sa0 = new SavingsAccount4 ( 1 , 21325302 , 0.015 ) ;
SavingsAccount4 sa1 = new SavingsAccount4 ( 1 , 58320212 , 0.015 ) ;
sa0. deposit ( 5 , 5000 ) ;
sa1. deposit ( 25 , 10000 ) ;
sa0. deposit ( 45 , 5500 ) ;
sa1. withdraw ( 60 , 4000 ) ;
sa0. settle ( 90 ) ;
sa1. settle ( 90 ) ;
sa0. show ( ) ;
sa1. show ( ) ;
}
} ;
2.第五章:增添静态属性和方法
class SavingsAccount5 {
private static double total;
private int id;
private double balance;
private double rate;
private int lastDate;
private double accumulation;
private void record ( int date, double amount) {
accumulation = accumulate ( date) ;
lastDate = date;
amount = Math. floor ( amount * 100 + 0.5 ) / 100 ;
balance += amount;
total += amount;
System. out. println ( date + "\t#" + id + "\t" + amount + "\t" + balance) ;
}
private double accumulate ( int date) {
return accumulation + balance * ( date - lastDate) ;
}
public SavingsAccount5 ( 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" ) ;
}
public int getId ( ) { return id; }
public double getBalance ( ) { return balance; }
public double getRate ( ) { return rate; }
public static double getTotal ( ) { return total; }
public void deposit ( int date, double amount) {
record ( date, amount) ;
}
public void withdraw ( int date, double amount) {
if ( amount > getBalance ( ) )
System. out. println ( "Error: not enough money" ) ;
else
record ( date, - amount) ;
}
public void settle ( int date) {
double interest = accumulate ( date) * rate / 365 ;
if ( interest != 0 )
record ( date, interest) ;
accumulation = 0 ;
}
public void show ( ) {
System. out. println ( "#" + id + "\tBalance: " + balance) ;
}
public static void main ( String[ ] args) {
SavingsAccount4 sa0 = new SavingsAccount4 ( 1 , 21325302 , 0.015 ) ;
SavingsAccount4 sa1 = new SavingsAccount4 ( 1 , 58320212 , 0.015 ) ;
sa0. deposit ( 5 , 5000 ) ;
sa1. deposit ( 25 , 10000 ) ;
sa0. deposit ( 45 , 5500 ) ;
sa1. withdraw ( 60 , 4000 ) ;
sa0. settle ( 90 ) ;
sa1. settle ( 90 ) ;
sa0. show ( ) ;
sa1. show ( ) ;
System. out. println ( "Total: " + SavingsAccount5. getTotal ( ) ) ;
}
}
3.第六章:增添字符串,对象数组
public class Date {
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;
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++ ;
}
public int getYear ( ) { return year; }
public int getMonth ( ) { return month; }
public int getDay ( ) { return day; }
public int getMaxDay ( ) {
if ( isLeapYear ( ) && month == 2 )
return 29 ;
else
return DAYS_BEFORE_MONTH[ month] - DAYS_BEFORE_MONTH[ month - 1 ] ;
}
boolean isLeapYear ( ) {
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0 ;
}
public void show ( ) {
System. out. println ( getYear ( ) + "-" + getMonth ( ) + "-" + getDay ( ) ) ;
}
public int distance ( Date date) {
return totalDays - date. totalDays;
}
}
public class Main {
public static void main ( String[ ] args) {
Date date = new Date ( 2008 , 11 , 1 ) ;
SavingsAccount accounts0 = new SavingsAccount ( date, "S3755217" , 0.015 ) ;
SavingsAccount accounts1 = new SavingsAccount ( date, "02342342" , 0.015 ) ;
accounts0. deposit ( new Date ( 2008 , 11 , 5 ) , 5000 , "salary" ) ;
accounts1. deposit ( new Date ( 2008 , 11 , 25 ) , 10000 , "sell stock 0323" ) ;
accounts0. deposit ( new Date ( 2008 , 12 , 5 ) , 5500 , "salary" ) ;
accounts1. withdraw ( new Date ( 2008 , 12 , 20 ) , 4000 , "buy a laptop" ) ;
System. out. println ( ) ;
accounts0. settle ( new Date ( 2009 , 1 , 1 ) ) ;
accounts0. show ( ) ;
System. out. println ( ) ;
accounts1. settle ( new Date ( 2009 , 1 , 1 ) ) ;
accounts1. show ( ) ;
System. out. println ( ) ;
System. out. println ( "Total: " + SavingsAccount. getTotal ( ) ) ;
}
}
class SavingsAccount {
private static double total = 0 ;
private String id;
private double balance;
private double rate;
private Date lastDate;
private double accumulation;
private void record ( Date date, double amount, String desc) {
accumulation = accumulate ( date) ;
lastDate = date;
amount = Math. floor ( amount * 100 + 0.5 ) / 100 ;
balance += amount;
total += amount;
System. out. println ( date + "\t#" + id + "\t" + amount + "\t" + balance+ "\t" + desc) ;
}
private void error ( String msg) {
System. out. println ( "Error(#" + id + "): " + msg) ;
}
double accumulate ( Date date) {
return accumulation + balance * date. distance ( lastDate) ;
}
public String getId ( ) { return id; }
public double getBalance ( ) { return balance; }
public double getRate ( ) { return rate; }
public static double getTotal ( ) { return total; }
public SavingsAccount ( Date date, String id, double rate) {
this . id= id;
this . balance= 0 ;
this . rate= rate;
this . lastDate= date;
this . accumulation= 0 ;
date. show ( ) ;
System. out. println ( "\t#" + id + " created" ) ;
}
public void deposit ( Date date, double amount, String desc) {
record ( date, amount, desc) ;
}
public void withdraw ( Date date, double amount, String desc) {
if ( amount > getBalance ( ) )
error ( "not enough money" ) ;
else
record ( date, - amount, desc) ;
}
public void settle ( 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 ;
}
public void show ( ) {
System. out. println ( id + "\tBalance: " + balance) ;
}
}
4.第七章:继承与派生,抽象出父类,增添子类
package SavingsAccount7;
public class Account {
private String id;
private double balance;
private static double total;
private Date lastDate;
private double value;
private double sum;
protected Account ( Date date, String id) {
this . id= id;
this . balance= 0 ;
date. show ( ) ;
System. out. println ( "\t#" + id + " created" ) ;
}
protected void record ( Date date, double amount, String desc) {
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) ;
}
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; }
void show ( ) {
System. out. println ( id + "\tBalance: " + balance) ;
}
}
public class Accumulator {
private Date lastDate;
private double value;
private double sum;
public Accumulator ( Date date, double value) {
this . lastDate= date;
this . value= value;
this . sum= 0 ;
}
public double getSum ( Date date) {
return sum + value * date. distance ( lastDate) ;
}
public void change ( Date date, double value) {
sum = getSum ( date) ;
lastDate = date;
this . value = value;
}
public void reset ( Date date, double value) {
lastDate = date;
this . value = value;
sum = 0 ;
}
}
public class CreditAccount extends Account {
private Accumulator acc;
private double credit;
private double rate;
private double fee;
final private double getDebt ( ) {
double balance = getBalance ( ) ;
return ( balance < 0 ? balance : 0 ) ;
}
CreditAccount ( final Date date, final String id, double credit, double rate, double fee) {
super ( date, id) ;
this . credit= credit;
this . rate= rate;
this . fee= fee;
this . acc= new Accumulator ( date, 0 ) ;
}
final double getCredit ( ) { return credit; }
final double getRate ( ) { return rate; }
final double getFee ( ) { return fee; }
final double getAvailableCredit ( ) {
if ( getBalance ( ) < 0 )
return credit + getBalance ( ) ;
else
return credit;
}
void deposit ( final Date date, double amount, final String desc) {
record ( date, amount, desc) ;
acc. change ( date, getDebt ( ) ) ;
}
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 ( ) ) ;
}
}
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 ( ) ) ;
}
final void show ( ) {
super . show ( ) ;
System. out. println ( "\tAvailable credit:" + getAvailableCredit ( ) ) ;
}
}
class Date {
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;
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++ ;
}
public int getYear ( ) { return year; }
public int getMonth ( ) { return month; }
public int getDay ( ) { return day; }
public int getMaxDay ( ) {
if ( isLeapYear ( ) && month == 2 )
return 29 ;
else
return DAYS_BEFORE_MONTH[ month] - DAYS_BEFORE_MONTH[ month - 1 ] ;
}
boolean isLeapYear ( ) {
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0 ;
}
void show ( ) {
System. out. println ( getYear ( ) + "-" + getMonth ( ) + "-" + getDay ( ) ) ;
}
int distance ( Date date) {
return totalDays - date. totalDays;
}
} ;
public class Main {
public static void main ( String[ ] args) {
Date date= new Date ( 2008 , 11 , 1 ) ;
SavingsAccount sa1= new SavingsAccount ( date, "S3755217" , 0.015 ) ;
SavingsAccount sa2= new SavingsAccount ( date, "02342342" , 0.015 ) ;
CreditAccount ca= new CreditAccount ( date, "C5392394" , 10000 , 0.0005 , 50 ) ;
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 ) ) ;
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 ( ) ) ;
}
}
public class SavingsAccount extends Account {
private Accumulator acc;
private double rate;
public SavingsAccount ( Date date, String id, double rate) {
super ( date, id) ;
this . rate= rate;
this . acc= new Accumulator ( date, 0 ) ;
}
public double getRate ( ) { return rate; }
public void deposit ( Date date, double amount, String desc) {
record ( date, amount, desc) ;
acc. change ( date, getBalance ( ) ) ;
}
public void withdraw ( Date date, double amount, String desc) {
if ( amount > getBalance ( ) ) {
error ( "not enough money" ) ;
} else {
record ( date, - amount, desc) ;
acc. change ( date, getBalance ( ) ) ;
}
}
public void settle ( 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 ( ) ) ;
}
}
5.第八章:多态特性
public abstract class Account {
private String id;
private double balance;
private static double total= 0 ;
final String getId ( ) { return id; }
final double getBalance ( ) { return balance; }
static double getTotal ( ) { return total; }
protected Account ( final Date date, final String id) {
this . id= id;
this . balance= 0 ;
date. show ( ) ;
System. out. println ( "\t#" + id + "created" ) ;
}
protected void record ( final Date date, double amount, final String desc) {
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) ;
}
void show ( ) {
System. out. print ( id + "\tBalance: " + balance) ;
}
abstract void deposit ( final Date date, double amount, final String desc) ;
abstract void withdraw ( final Date date, double amount, final String desc) ;
abstract void settle ( final Date date) ;
protected final void error ( final String msg) {
System. out. println ( "Error(#" + id + "): " + msg + "\n" ) ;
}
}
public class Accumulator {
private Date lastDate;
private double value;
private double sum;
Accumulator ( final Date date, double value) {
this . lastDate = date;
this . value = value;
this . sum = 0 ;
}
final double getSum ( final Date date) {
return sum + value * ( date. getTotalDays ( ) - lastDate. getTotalDays ( ) ) ;
}
void change ( final Date date, double value) {
sum = getSum ( date) ;
lastDate = date;
this . value = value;
}
void reset ( final Date date, double value) {
lastDate = date;
this . value = value;
sum = 0 ;
}
}
public class CreditAccount extends Account {
private Accumulator acc;
private double credit;
private double rate;
private double fee;
final private double getDebt ( ) {
double balance = getBalance ( ) ;
return ( balance < 0 ? balance : 0 ) ;
}
CreditAccount ( final Date date, final String id, double credit, double rate, double fee)
{ super ( date, id) ;
this . credit= credit;
this . rate= rate;
this . fee= fee;
this . acc= new Accumulator ( date, 0 ) ;
}
final double getCredit ( ) { return credit; }
final double getRate ( ) { return rate; }
final double getFee ( ) { return fee; }
final double getAvailableCredit ( ) {
if ( getBalance ( ) < 0 )
return credit + getBalance ( ) ;
else
return credit;
}
void deposit ( final Date date, double amount, final String desc) {
record ( date, amount, desc) ;
acc. change ( date, getDebt ( ) ) ;
}
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 ( ) ) ;
}
}
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 ( ) ) ;
}
final void show ( ) {
super . show ( ) ;
System. out. println ( "\tAvailable credit:" + getAvailableCredit ( ) ) ;
}
}
public class Date {
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;
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++ ;
}
final int getYear ( ) {
return year;
}
int getTotalDays ( ) {
return this . totalDays;
}
final int getMonth ( ) {
return month;
}
final int getDay ( ) {
return day;
}
final int getMaxDay ( ) {
if ( isLeapYear ( ) && month == 2 )
return 29 ;
else
return DAYS_BEFORE_MONTH[ month] - DAYS_BEFORE_MONTH[ month - 1 ] ;
} ;
final boolean isLeapYear ( ) {
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0 ;
}
final void show ( ) {
System. out. print ( getYear ( ) + "-" + getMonth ( ) + "-" + getDay ( ) ) ;
}
}
import java. util. Scanner;
public class Main {
public static void main ( String[ ] args) {
Date date= new Date ( 2008 , 11 , 1 ) ;
SavingsAccount sa1= new SavingsAccount ( date, "S3755217" , 0.015 ) ;
SavingsAccount sa2= new SavingsAccount ( date, "02342342" , 0.015 ) ;
CreditAccount ca= new CreditAccount ( date, "C5392394" , 10000 , 0.0005 , 50 ) ;
Account accounts[ ] = { sa1, sa2, ca } ;
final int n = accounts. length;
System. out. println ( "(d)deposit (w)withdraw (s)show (c)change day (n)next month (e)exit" ) ;
Scanner sc = new Scanner ( System. in) ;
char cmd = '0' ;
do {
date. show ( ) ;
System. out. println ( "\tTotal: " + Account. getTotal ( ) + "\tcommand> " ) ;
int index, day;
double amount;
String desc;
System. out. println ( "请输入指令 cmd:" ) ;
cmd= sc. next ( ) . charAt ( 0 ) ;
switch ( cmd) {
case 'd' :
System. out. println ( "请输入账户数组下标index:" ) ;
index= sc. nextInt ( ) ;
System. out. println ( "请输入存款金额amount:" ) ;
amount= sc. nextDouble ( ) ;
System. out. println ( "请输入存款项目名称desc:" ) ;
desc= sc. nextLine ( ) ;
accounts[ index] . deposit ( date, amount, desc) ;
break ;
case 'w' :
System. out. println ( "请输入账户数组下标index:" ) ;
index= sc. nextInt ( ) ;
System. out. println ( "请输入取款金额amount:" ) ;
amount= sc. nextDouble ( ) ;
System. out. println ( "请输入取款项目名称desc:" ) ;
desc= sc. 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' :
System. out. println ( "请输入日期day:" ) ;
day= sc. 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' ) ;
sc. close ( ) ;
}
}
public class SavingsAccount extends Account {
private Accumulator acc;
private double rate;
final double getRate ( ) {
return rate;
}
SavingsAccount ( final Date date, String id, double rate) {
super ( date, id) ;
this . rate = rate;
this . acc = new Accumulator ( date, 0 ) ;
}
void deposit ( final Date date, double amount, final String desc) {
record ( date, amount, desc) ;
acc. change ( date, getBalance ( ) ) ;
}
void withdraw ( final Date date, double amount, final String desc) {
if ( amount > getBalance ( ) ) {
error ( "not enough money" ) ;
} else {
record ( date, - amount, desc) ;
acc. change ( date, getBalance ( ) ) ;
}
}
void settle ( final Date date) {
if ( date. getMonth ( ) == 1 ) {
double interest = acc. getSum ( date) * rate
/ ( date. getTotalDays ( ) - ( new Date ( date. getYear ( ) - 1 , 1 , 1 ) ) . getTotalDays ( ) ) ;
if ( interest != 0 )
record ( date, interest, "interest" ) ;
acc. reset ( date, getBalance ( ) ) ;
}
}
}
6.第九章:使用容器代替数组
package SavingsAccount9;
public abstract class Account {
private String id;
private double balance;
private static double total= 0 ;
final String getId ( ) { return id; }
final double getBalance ( ) { return balance; }
static double getTotal ( ) { return total; }
protected Account ( final Date date, final String id) {
this . id= id;
this . balance= 0 ;
date. show ( ) ;
System. out. println ( "\t#" + id + "created" ) ;
}
protected void record ( final Date date, double amount, final String desc) {
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) ;
}
void show ( ) {
System. out. print ( id + "\tBalance: " + balance) ;
}
abstract void deposit ( final Date date, double amount, final String desc) ;
abstract void withdraw ( final Date date, double amount, final String desc) ;
abstract void settle ( final Date date) ;
protected final void error ( final String msg) {
System. out. println ( "Error(#" + id + "): " + msg + "\n" ) ;
}
}
package SavingsAccount9;
public class Accumulator {
private Date lastDate;
private double value;
private double sum;
Accumulator ( final Date date, double value) {
this . lastDate = date;
this . value = value;
this . sum = 0 ;
}
final double getSum ( final Date date) {
return sum + value * ( date. getTotalDays ( ) - lastDate. getTotalDays ( ) ) ;
}
void change ( final Date date, double value) {
sum = getSum ( date) ;
lastDate = date;
this . value = value;
}
void reset ( final Date date, double value) {
lastDate = date;
this . value = value;
sum = 0 ;
}
}
public class CreditAccount extends Account {
private Accumulator acc;
private double credit;
private double rate;
private double fee;
final private double getDebt ( ) {
double balance = getBalance ( ) ;
return ( balance < 0 ? balance : 0 ) ;
}
CreditAccount ( final Date date, final String id, double credit, double rate, double fee)
{ super ( date, id) ;
this . credit= credit;
this . rate= rate;
this . fee= fee;
this . acc= new Accumulator ( date, 0 ) ;
}
final double getCredit ( ) { return credit; }
final double getRate ( ) { return rate; }
final double getFee ( ) { return fee; }
final double getAvailableCredit ( ) {
if ( getBalance ( ) < 0 )
return credit + getBalance ( ) ;
else
return credit;
}
void deposit ( final Date date, double amount, final String desc) {
record ( date, amount, desc) ;
acc. change ( date, getDebt ( ) ) ;
}
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 ( ) ) ;
}
}
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 ( ) ) ;
}
final void show ( ) {
super . show ( ) ;
System. out. println ( "\tAvailable credit:" + getAvailableCredit ( ) ) ;
}
}
public class Date {
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;
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++ ;
}
final int getYear ( ) {
return year;
}
int getTotalDays ( ) {
return this . totalDays;
}
final int getMonth ( ) {
return month;
}
final int getDay ( ) {
return day;
}
final int getMaxDay ( ) {
if ( isLeapYear ( ) && month == 2 )
return 29 ;
else
return DAYS_BEFORE_MONTH[ month] - DAYS_BEFORE_MONTH[ month - 1 ] ;
} ;
final boolean isLeapYear ( ) {
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0 ;
}
final void show ( ) {
System. out. print ( getYear ( ) + "-" + getMonth ( ) + "-" + getDay ( ) ) ;
}
}
import java. util. ArrayList;
import java. io. *;
public class Main {
public static void main ( String[ ] args) {
Date date= new Date ( 2008 , 11 , 1 ) ;
ArrayList< Account> accounts= new ArrayList < Account> ( ) ;
System. out. println ( "(a)add account (d)deposit (w)withdraw (s)show (c)change day (n)next month (e)exit" ) ;
char cmd= '0' ;
Scanner sc = new Scanner ( System. in) ;
do {
date. show ( ) ;
System. out. println ( "\tTotal: " + Account. getTotal ( ) + "\tcommand> " ) ;
char type= '0' ;
int index, day;
double amount, credit, rate, fee;
String id, desc;
System. out. println ( "请输入指令 cmd:" ) ;
cmd= sc. next ( ) . charAt ( 0 ) ;
switch ( cmd) {
case 'a' :
try {
System. out. println ( "请输入账户类型(s:SavingAccount 其它:CreditAccount):" ) ;
type= ( char ) System. in. read ( ) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
System. out. println ( "请输入id:" ) ;
id= sc. next ( ) ;
if ( type == 's' ) {
System. out. println ( "请输入存款的年利率rate:" ) ;
rate= sc. nextDouble ( ) ;
accounts. add ( new SavingsAccount ( date, id, rate) ) ;
} else {
System. out. println ( "请输入信用额度credit:" ) ;
credit= sc. nextDouble ( ) ;
System. out. println ( "请输入欠款的日利率rate:" ) ;
rate= sc. nextDouble ( ) ;
System. out. println ( "请输入信用卡年费fee:" ) ;
fee= sc. nextDouble ( ) ;
accounts. add ( new CreditAccount ( date, id, credit, rate, fee) ) ;
}
break ;
case 'd' :
System. out. println ( "请输入账户数组下标index:" ) ;
index= sc. nextInt ( ) ;
System. out. println ( "请输入存款金额amount:" ) ;
amount= sc. nextDouble ( ) ;
System. out. println ( "请输入存款项目名称desc:" ) ;
desc= sc. nextLine ( ) ;
accounts. get ( index) . deposit ( date, amount, desc) ;
break ;
case 'w' :
System. out. println ( "请输入账户数组下标index:" ) ;
index= sc. nextInt ( ) ;
System. out. println ( "请输入取款金额amount:" ) ;
amount= sc. nextDouble ( ) ;
System. out. println ( "请输入取款项目名称desc:" ) ;
desc= sc. nextLine ( ) ;
accounts. get ( index) . withdraw ( date, amount, desc) ;
break ;
case 's' :
for ( int i = 0 ; i < accounts. size ( ) ; i++ ) {
System. out. print ( "[" + i + "] " ) ;
accounts. get ( i) . show ( ) ;
System. out. println ( ) ;
}
break ;
case 'c' :
System. out. println ( "请输入日期day:" ) ;
day= sc. 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 < accounts. size ( ) ; i++ )
accounts. get ( i) . settle ( date) ;
break ;
}
} while ( cmd != 'e' ) ;
sc. close ( ) ;
accounts. clear ( ) ;
}
}
public class SavingsAccount extends Account {
private Accumulator acc;
private double rate;
final double getRate ( ) { return rate; }
SavingsAccount ( final Date date, String id, double rate) {
super ( date, id) ;
this . rate= rate;
this . acc= new Accumulator ( date, 0 ) ;
}
void deposit ( final Date date, double amount, final String desc) {
record ( date, amount, desc) ;
acc. change ( date, getBalance ( ) ) ;
}
void withdraw ( final Date date, double amount, final String desc) {
if ( amount > getBalance ( ) ) {
error ( "not enough money" ) ;
} else {
record ( date, - amount, desc) ;
acc. change ( date, getBalance ( ) ) ;
}
}
void settle ( final Date date) {
if ( date. getMonth ( ) == 1 ) {
double interest = acc. getSum ( date) * rate
/ ( date. getTotalDays ( ) - ( new Date ( date. getYear ( ) - 1 , 1 , 1 ) ) . getTotalDays ( ) ) ;
if ( interest != 0 )
record ( date, interest, "interest" ) ;
acc. reset ( date, getBalance ( ) ) ;
}
}
}