Java程序辅导

C C++ Java Python Processing编程在线培训 程序编写 软件开发 视频讲解

客服在线QQ:2653320439 微信:ittutor Email:itutor@qq.com
wx: cjtutor
QQ: 2653320439
DCS 235 Software Engineering
Lab 1: Answer Sheet
Programming in the Large: Building a Bank
version 1.1, October 2003
1.The Account Class – Project0
See the BlueJ project project0_answer.
2.Transactions – Project1 
See the BlueJ project project1_answer.
1. Classes ‘Withdrawal’ and ‘Deposit’ extend ‘Transaction’.  The methods marked final in
‘Transaction’ do not need to be implemented in the extension classes, just the constructor and the
methods ‘getValue’ and ‘printTransactions’.
public class Deposit extends Transaction {
    /**
     * Calls the constructor for transaction
     */
    public Deposit(int day, int amount)
    {
        super(day, amount);
    }
    /**
     * Get the value of this deposit.
     * 
     * @return This transaction amount in pence.
     */
    public int getValue() {
        return this.amount ;
    }
    /**
     * Print a description of this deposit to the console.
     */
    public void printTransaction() {
        System.out.println("Deposited " + poundsAndPence(amount) 
                           + " on day " + day) ; 
    }
Plus a copy of the ‘PoundsAndPence’ method.
2. The method ‘getCurrentBalance’ and ‘showStatement’ both need to iterate down the list of
transactions.  E.g.
    private int getCurrentBalance()
    {
        int currentBalance = balance ;
        Transaction t = first ;
        while (t != null) {
            currentBalance += t.getValue() ;
DCS235 Lab 1 Answers (version 1.1_0, Oct 6, 03) Page 1
            t = t.getNext() ;
        } 
        return currentBalance ;
    }
3. The ‘poundsAndPence’ method can be copied to Transaction or its subclasses, or made
public.  Neither of these solution is satisfactory since they lack encapsulation. 
3.Reorganising the Code – Project2
See the BlueJ project project2_answer.
1. poundsAndPence:  The obvious solution is a class ‘Money’, with a method ‘toString’.  This is
useful encapsulation, since we can think of money as being pounds and pence.  The
implementation of this as an integer is hidden in the Money class.  Money is then used to replace
integer amounts in the Account and Transaction classes.
• Negative money: need to be careful about the money amount in the Withdraw transaction.  It
is stored as a positive amount, but ‘getValue’ returns a 
• Cloning money: the money class needs a clone method1.  Using clone in the right places is a
good test of understanding of Java’s use of references.  For example, when amount is a
primitive type (int) the ‘getValue’ method of ‘Withdraw’ is:
    public int getValue() {
        return - this.amount ;
    }
When amount is of type Money, the ‘getValue’ implementation is:
     public Money getValue() {
        Money m = (Money) amount.clone() ;
        m.negate() ;
        return m ;
    }
2. Current balance: Instead of iterating over the list of transactions, now the program maintains an
invariant – the ‘balance’ field is always equal to the sum of the transactions.
3. ‘Opening’ transaction type.  So that the opening balance isn’t lost, we need a new transaction
type, just for the opening balance.  The class diagram now looks like:
1 The reason a clone method is needed is to avoiding changing the value of a Money object when the original value is
still being used.  Clone is called before calling ‘negate’ or ‘add’, unless it is clear that the original value is not
needed.  An alternative and possibly better solution is make Money ‘immutable’ (see Jia page 20/21).  This means
that an amount of money is never changed.  The methods negate() and add() change too – so that a.add(b), instead
of changing (mutating) the value of a, creates a new Money object c, where c.value = a.value + b.value.  This
solution is safer – no clone() method is needed and it is not possible to forgot to clone when you should.
DCS235 Lab 1 Answers (version 1.1_0, Oct 6, 03) Page 2
The opening transaction extends deposit.  All we need to do is to call the parent’s constructor and
override the print method:
public class Opening extends Deposit {
    /**
     * Calls the constructor for transaction
     */
    public Opening(Money amount) {
        super(1, amount);
    }
    /**
     * Print a description of this deposit to the console.
     */
    public void printTransaction() {
        System.out.println("Opening balance " + amount.toString() 
                           + " on day " + day) ; 
    }
}
4.Monthly Statements – Project3
See project3_answer, which also includes the interest calculation.
The key step is to introduce a class ‘Month’ (maybe ‘Statement’ or ‘StatementPeriod’ would be
better names).  An account has many months.  So that the opening balance isn’t lost, a new type of
transaction ‘Opening’ is added.  The class diagram is: 
Many to one relationships.  An account has many months and a month has many transactions.  In
DCS235 Lab 1 Answers (version 1.1_0, Oct 6, 03) Page 3
Account Transaction
Deposit Withdraw
Opening
Month Transaction
Deposit Withdraw
Opening
Account
1
1 *
*
this example, these many-to-one relationships have been implemented in different ways: a linked-
list for the transactions and an array of months.  It would be better to use a collection (see Jia section
8.2).
5.Challenge Problem – Interest Calculation
We need to calculate the interest payable on each day.  There is obviously a danger of losing it in
rounding errors.  One solution would be to hold money a greater accuracy – now that money is
‘encapsulated’ in a class this would be easy to do.
Instead, we add up the daily balance first and then calculate the interest on the sum.  To get the daily
balance, we add up all the transaction for the same day.  The code here assumes that the list of
transaction is in order by day – unfortunately this isn’t guaranteed, though we can check for it.  A
better solution would be to use collections.  Here is the key part of the code:
        for (int day = 1; day <= 30; day++) {
            // sum any transactions for today, if any
            while (t != null && t.getDay() == day) {
                dailyBalance.add(t.getValue()) ;
                t = t.getNext() ;
            } ;
            // discard and warn about any out of order transactions
            while (t != null && t.getDay() < day) {
                System.out.println("**WARNING** Transaction out of order") ;
                t = t.getNext() ;
            } ;
            // add dailyBalance to sum
            if (dailyBalance.isNegative()) {
                sumODrawn.add(dailyBalance) ; 
            } else {
                sumCredit.add(dailyBalance) ; 
            }
        } ;
Note that two sums are accumulated.  One for all daily balances; one for any days when the account
is overdrawn.  We use the overdraft sum if it is not zero and the other sum otherwise.
This code fits into a routine to close a month.  At the end of each month an interest transaction is
added to the account – another extension of deposit.
DCS235 Lab 1 Answers (version 1.1_0, Oct 6, 03) Page 4