The Artima Developer Community
Sponsored Link

Objects and Java Seminar
Composition and Inheritance
Lecture Handout

Agenda


Code Reuse in Java

When you need a class, you can:

Composition vs. Inheritance


Composition Syntax


Inheritance Syntax


What Inheritance Means


Inheritance Example

 1 package com.artima.examples.account.ex1;
 2
 3 /**
 4 * Represents a bank account. Money is stored in this account
 5 * in integral units. Clients can use this account to store
 6 * any kind of value, such as money or points, etc. The meaning
 7 * of the integral units stored in this account is a decision
 8 * of the client that instantiates the account. The maximum
 9 * amount of units that can be stored as the current balance of
10 * an <code>Account</code> is Long.MAX_VALUE.
11 */
12 public class Account {
13
14     /**
15     * The current balance
16     */
17     private long balance;
18
19     /**
20     * Withdraws exactly the passed amount from the
21     * <code>Account</code>. Subclasses must withdraw
22     * at least the passed amount, but may effectively withdraw more.
23     * For example, if a subclass includes the notion of
24     * a withrawal fee, the subclass's implementation of
25     * this method may charge that fee by decrementing it
26     * from the account at the time of withdrawal.
27     *
28     * @param amount amount to withdraw
29     * @returns amount withdrawn from the <code>Account</code>
30     * @throws InsufficientFundsException if the <code>Account</code>
31     *     contains insufficient funds for the requested withdrawal
32     */
33     public long withdraw(long amount)
34         throws InsufficientFundsException {
35
36         if (amount > balance) {
37             throw new InsufficientFundsException(
38                 amount - balance);
39         }
40
41         balance -= amount;
42         return amount;
43     }
44
45     /**
46     * Deposits exactly the passed amount into the <code>Account</code>.
47     * Subclasses may effectively deposit more or less than the passed
48     * amount into the <code>Account</code>. For example, if a subclass
49     * includes the notion of funds matching, the subclass implementation
50     * of this method may match some or all of the deposited amount at
51     * the time of deposit, effectively increasing the deposited amount.
52     * Or, if a subclass includes the notion of
53     * a deposit fee, the subclass's implementation of
54     * this method may charge that fee by decrementing it
55     * from the account at the time of withdrawal, effectively reducing
56     * the deposited amount.
57     *
58     * @param amount amount to deposit
59     * @throws ArithmeticException if requested deposit would cause the
60     *     balance of this <code>Account</code> to exceed Long.MAX_VALUE.
61     */
62     public void deposit(long amount) {
63
64         // TO DO: Check for overflow
65         balance += amount;
66     }
67
68     /**
69     * Gets the current balance of this <code>Account</code>
70     *
71     * @returns the current balance
72     */
73     public long getBalance() {
74         return balance;
75     }
76 }
77

  1 package com.artima.examples.account.ex1;
  2
  3 /**
  4 * Represents a bank account with overdraft protection. Instances
  5 * of this class are instantiated with a specified maximum
  6 * overdraft. If a client attempts to withdraw more than the
  7 * current account balance, the bank may loan the amount in
  8 * excess of the balance to the client. The overdraft maximum
  9 * passed to an <code>OverdraftAccount</code>'s constructor
 10 * is the maximum amount the bank will lend to the client in
 11 * this manner. When a client makes a deposit, the bank will
 12 * pay itself back first before increasing the account's balance.
 13 *
 14 * <p>
 15 * As described in class <code>Account</code>, money is stored in
 16 * this account in integral units. Clients
 17 * can use this account to store any kind of value, such as money
 18 * or points, etc. The meaning of the integral units stored in
 19 * this account is a decision of the client that instantiates the
 20 * account. The maximum amount of units that can be stored as
 21 * the current balance of an <code>Account</code> is Long.MAX_VALUE.
 22 */
 23 public class OverdraftAccount extends Account {
 24
 25     /**
 26     * The maximum amount the bank will loan to the client.
 27     */
 28     private final long overdraftMax;
 29
 30     /**
 31     * The current amount the bank has loaned to the client
 32     * which has not yet been repaid. This must be zero to
 33     * overdraftMax.
 34     */
 35     private long overdraft;
 36
 37     /**
 38     * Constructs a new <code>OverdraftAccount</code> with the
 39     * passed <code>overdraftMax</code>.
 40     *
 41     * @param overdraftMax the maximum amount the bank will loan
 42     *     to the client
 43     */
 44     public OverdraftAccount(long overdraftMax) {
 45         this.overdraftMax = overdraftMax;
 46     }
 47
 48     /**
 49     * Returns the current overdraft, the amount the bank has
 50     * loaned to the client that has not yet been repaid.
 51     *
 52     * @returns the current overdraft
 53     */
 54     public long getOverdraft() {
 55         return overdraft;
 56     }
 57
 58     /**
 59     * Returns the overdraft maximum, the maximum amount the
 60     * bank will allow the client to owe it. For each instance
 61     * of <code>OverdraftAccount</code>, the overdraft maximum
 62     * is constant.
 63     *
 64     * @returns the overdraft maximum
 65     */
 66     public long getOverdraftMax() {
 67         return overdraftMax;
 68     }
 69
 70     /**
 71     * Withdraws exactly the passed amount from the
 72     * <code>Account</code>. If the passed amount is
 73     * less than or equal to the current balance, all withdrawn
 74     * funds will be taken from the balance, and the balance
 75     * will be decremented by the passed amount. If the passed amount
 76     * exceeds the current balance, the bank may loan the client the
 77     * difference. The bank will make the loan only if the difference
 78     * between the passed amount and the balance is less than or equal to
 79     * the available overdraft. The available overdraft is equal to
 80     * the current overdraft (the amount already loaned to the client and
 81     * not yet repaid), subtracted from the overdraft maximum, which
 82     * is passed to the constructor of any <code>OverdraftAccount</code>.
 83     *
 84     * <p>
 85     * If the passed amount less the current balance is less than or equal
 86     * to the available overdraft, the <code>withdraw</code> method returns
 87     * the requested amount, sets the current balance to zero, and records
 88     * the loan. Otherwise, if the passed amount less the current balance
 89     * exceeds the available overdraft, the <code>withdraw</code> method throws
 90     * <code>InsufficientFundsException</code>.
 91     *
 92     * @param amount amount to withdraw
 93     * @returns amount withdrawn from the <code>Account</code>
 94     * @throws InsufficientFundsException if the <code>Account</code>
 95     *     contains insufficient funds for the requested withdrawal
 96     */
 97     public long withdraw(long amount)
 98         throws InsufficientFundsException {
 99
100         long balance = getBalance();
101         if (balance >= amount) {
102
103             // Balance has sufficient funds, just take the
104             // money from the balance.
105             balance -= amount;
106             return amount;
107         }
108
109         long shortfall = amount - balance;
110         long extraAvailable = overdraftMax - overdraft;
111
112         if (shortfall > extraAvailable) {
113             throw new InsufficientFundsException(shortfall - extraAvailable);
114         }
115         overdraft += shortfall;
116         super.withdraw(amount - shortfall);
117
118         return amount;
119     }
120
121     /**
122     * Deposits exactly the passed amount into the <code>Account</code>.
123     * If the current overdraft is zero, the balance will be increased
124     * by the passed amount. Otherwise, the bank will attempt to pay
125     * off the overdraft first, before increasing the current balance
126     * by the amount remaining after the overdraft is repaid, if any.
127     *
128     * <p>
129     * For example, if the balance is 200, the overdraft is 100, and the
130     * <code>deposit</code> method is invoked with a passed <code>amount</code>
131     * of 50, the bank would use all 50 of those monetary units to pay down
132     * the overdraft. The overdraft would be reduced to 50 and the balance would
133     * remain at 200. If subsequently, the client deposits another 100 units,
134     * the bank would use 50 of those units to pay off the overdraft loan and
135     * direct the remaining 50 into the balance. The new overdraft would
136     * be 0 and the new balance would be 250.
137     *
138     * @param amount amount to deposit
139     * @throws ArithmeticException if requested deposit would cause the
140     *     balance of this <code>Account</code> to exceed Long.MAX_VALUE.
141     */
142     public void deposit(long amount) {
143         if (overdraft > 0) {
144             if (amount < overdraft) {
145                 overdraft -= amount;
146             }
147             else {
148                 long diff = amount - overdraft;
149                 overdraft = 0;
150                 super.deposit(diff);
151             }
152         }
153         else {
154             super.deposit(amount);
155         }
156     }
157 }

Order of Initialization


super() Invocations


The final Keyword


Final Fields


Final Methods and Classes


Exercises

Problem 1.

Create two classes, Shape and Circle. Have class Circle extend class Shape. Create a static method in class Shape called sayHello() that prints "Nice Form!" to the standard output. Declare a method with the same name and signature in class Circle that prints out "Well-rounded!" to the standard output. Create a class named Problem1 with a main() method that creates a Circle object and stores its reference in a variable of type Shape. Invoke sayHello() on the reference to the Circle object.

Problem 2.

Create two classes, Vehicle and Engine, with no-arg constructors. Vehicle's constructor should print "I'm a Vehicle!" to the standard output, and Engine's constructor should print "I'm an Engine!". Create a new class PickupTruck and declare it a subclass of Vehicle. Create an instance variable in PickupTruck that is of type Engine and initialize it (with an initializer) to a new instance of class Engine. Class PickupTruck should have no constructors or methods, just the instance variable. In the main() method of a class named Problem2, create an object of class PickupTruck. Run the Problem2 application and observe the results.

Problem 3.

Create two classes, Boat and Motor, each with one constructor that takes a single parameter of type String. Both of these constructors should simply print the passed String to the standard output. Create a new class SpeedBoat and declare it a subclass of Boat. Create an instance variable in SpeedBoat that is of type Motor and initialize it (with an initializer) to a new instance of class Motor. Pass the String, "I'm a Motor!" to the Motor constructor. Give SpeedBoat a constructor that takes a String parameter. SpeedBoat's constructor should have only one statement, a super() invocation that sends the passed parameter up to the superclass constructor. When you're done, class SpeedBoat should have only one constructor and one instance variable. In the main() method of a class named Problem3, create an object of class SpeedBoat, passing in the String, "I'm a SpeedBoat!". Run the Problem3 application and observe the results.

Problem 4.

Create an inheritance hierarchy of Rodent: Mouse, Gerbil, Hamster, etc. In the base class, provide methods that are common to all Rodents, and override these in the derived classes to perform different behaviors depending on the specific type of Rodents. In the main() method of a class named Problem4, create an array of Rodent, fill it with different specific types of Rodents, and call your base-class methods to see what happens.


Sponsored Links

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use