JMU
Polymorphism through Inheritance
With Examples in Java


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu


Review - The Syntax of Specialization
Review (cont.)
Review (cont.)
Motivation of this Lecture
Polymorphism
A Simple Example

Recall the Instant Messaging Example

javaexamples/oopbasics/im2/Chirp.java
import java.util.*;

/**
 * A missive in an instant messaging system
 *
 * @author  Prof. David Bernstein
 * @version 2.0
 */
public class Chirp
{
    protected String          delimiters;  // Delimiters between words
    protected String          text;        // The text of the message

    /**
     * Explicit Value Constructor
     *
     * @param typed   What was typed by the user
     */
    public Chirp(String typed)
    {
        text       = typed;
        delimiters = " ,.;!?-\n\r";
    }

    /**
     * Get the number of words in this Chirp
     *
     * @return   The number of words
     */
    public int getNumberOfWords()
    {
        int                 numberOfWords;
        StringTokenizer     tokenizer;

        tokenizer     = new StringTokenizer(text, delimiters);
        numberOfWords = tokenizer.countTokens();

        return numberOfWords;
    }

    /**
     * Get the text of this Chirp
     *
     * @return   The text
     */
    protected String getText()
    {
        return text;
    }
}
        
A Simple Example (cont.)

Recall the Instant Messaging Example

javaexamples/oopbasics/im2/ExpandedChirp.java
import java.io.*;
import java.util.*;

/**
 * A missive in an instant messaging system
 *
 * Unlike a normal Chirp, an ExpandedChirp does not
 * contain abbreviations -- they are all expanded
 *
 * @author  Prof. David Bernstein
 * @version 2.0
 */
public class ExpandedChirp extends Chirp
{
    private Properties      abbreviations;


    /**
     * Explicit Value Constructor
     *
     * @param typed   What was typed by the user
     */
    public ExpandedChirp(String typed)
    {
        super(typed);
        InputStream      is;

        abbreviations = new Properties();
        try 
        {
            is = new FileInputStream("abbreviations.txt");
            abbreviations.load(is);
        } 
        catch (IOException ioe)
        {
            // There was a problem opening the file
            // containing the abbreviations
        }
    }

    /**
     * Get the text of this Chirp with all of the
     * abbreviations expanded
     *
     * @return   The text
     */
    public String getText()
    {
        String       tempText;

        // Use the protected attribute in the parent
        tempText  = replaceAbbreviations(text);

        return tempText;
    }

    /**
     * Replace the abbreviations in a message
     *
     * @param msg   The original message
     */
    private String replaceAbbreviations(String msg)
    {
        String              replaced, token, word;
        StringTokenizer     tokenizer;

        replaced = "";
        
        // Use the protected attribute in the parent
        tokenizer = new StringTokenizer(msg, delimiters, true);
        while (tokenizer.hasMoreTokens())
        {
            token = tokenizer.nextToken();
            word  = abbreviations.getProperty(token);

            if (word == null) replaced += token;
            else              replaced += word;
        }

        return replaced;
    }
}
        
A Simple Example (cont.)

Since an ExpandedChirp "is a" Chirp, we know that a Chirp[] (i.e., an array of references to Chirp objects) can contain both.

javaexamples/oopbasics/im2/ChirpRecorder.java
/**
 * A missive recorder in an instant messaging system.
 * In this version, there is a limit on the total number
 * of Chirp objects that can be recorded and all output is
 * sent to the console.
 *
 * @author  Prof. David Bernstein
 * @version 2.0
 */
public class ChirpRecorder
{
    private int            currentNumber;
    private Chirp[]        chirps;

    /**
     * Explicit Value Constructor
     *
     * @param size   The maximum number of Chirp objects to be recorded
     */
    public ChirpRecorder(int size)
    {
        chirps        = new Chirp[size];
        currentNumber = 0;
    }

    /**
     * Add a Chirp to this ChirpRecorder (if it is not
     * already full)
     *
     * @param msg   The Chirp to record
     */
    public void addChirp(Chirp msg)
    {
        if (currentNumber < chirps.length) {

            chirps[currentNumber] = msg;
            currentNumber++;
        }
    }

    /**
     * Show (on System.out) a previously recorded Chirp
     *
     * @param number   The number of the Chirp to show
     */
    public void showChirp(int number)
    {
        String     text;

        if (number < currentNumber) 
        {
            text = chirps[number].getText();
            System.out.println(text);
        } 
        else
        {
            System.out.println("No such chirp!");
        }
    }
}
        
A Simple Example (cont.)

What we need to know is what happens when an element's getText() method is called.

javaexamples/oopbasics/im2/Driver.java
/**
 * A driver for an instant messaging system.
 *
 * @author  Prof. David Bernstein
 * @version 2.0
 */
public class Driver
{
    /**
     * The entry point of the application
     *
     * @param args   The command line arguments
     */
    public static void main(String[] args)
    {
        ExpandedChirp  english;
        Chirp          message;
        ChirpRecorder  recorder;


        recorder = new ChirpRecorder(10);

        message = new Chirp("FWIW I think he's arrogant. G2G");
        recorder.addChirp(message);

        english = new ExpandedChirp("SLAP.  TTYL");
        recorder.addChirp(english);

        System.out.println("\n\n");
        System.out.println("Showing 0 (a Chirp):\n");
        recorder.showChirp(0);
        


        System.out.println("\n\n");
        System.out.println("\nShowing 1 (an ExpandedChirp):\n");
        recorder.showChirp(1);
        
    }
}
        
A Simple Example (cont.)

What Memory Might Look Like Before The Calls To recorder.showChirp()

images/JavaMemoryModel_ChirpExample.png
New Terminology
Polymorphism in Java
A More Complicated Example
javaexamples/oopbasics/banking/Account.java
/**
 * A simple "bank" Account
 *
 * @version 1.0
 * @author  Prof. David Bernstein, James Madison University
 */
public class Account
{
    protected double balance;
    protected int    id;

    /**
     * Default constructor
     */
    public Account() 
    {

        balance = 0;
        id = -1;
    }

    /**
     * Explicit Value Constructor
     *
     * @param idNumber        The ID for the Account
     * @param initialDeposit  The initial deposit
     */
    public Account(int idNumber, double initialDeposit)
    {
        balance = 0;

        id = idNumber;
        if (initialDeposit > 0) balance = initialDeposit;
    }

    /**
     * Determine the maximum amount that can be withdrawn
     *
     * @return The size of the maximum possible withdrawal
     */
    public double amountAvailable()
    {
        return balance;
    }

    /**
     * Deposit money in this Account
     *
   * @param amount    The size of the deposit
   *
   * @return false if unable to deposit and true otherwise
   */
    public boolean deposit(double amount)
    {
        boolean ok;

        ok = false;
        if (amount >= 0) {

            balance += amount;
            ok = true;
        }

        return ok;
    }

    /**
     * Obtain the ID of this Account
     *
     * @return The ID of this Account
     */
    public int getID()
    {
        return id;
    }
  
    /**
     * Withdraw money from this Account
     *
     * @param amount   The size of the withdrawal
     *
     * @return false if unable to withdraw and true otherwise
     */
    public boolean withdraw(double amount)
    {
        boolean     ok;

        ok = false;
        if (amount >= 0) {

            // Check if available funds are sufficient
            // 
            // Note: amountAvailble() is overriden in the 
            // derived class OverdraftAccount.
            // Which version of amountAvailable() will be 
            // called?
            //
            if (amountAvailable() >= amount) {

                balance -= amount;
                ok = true;
            }
        }

        return ok;
    }
}
        
A More Complicated Example (cont.)
javaexamples/oopbasics/banking/OverdraftAccount.java
/**
 * A "bank" Account that allows the owner to withdraw more money
 * than is in the account 
 *
 * @version 1.0
 * @author  Prof. David Bernstein, James Madison University
 */
public class OverdraftAccount extends Account
{
    protected double   overdraftLimit;

    /**
     * Constructor
     *
     * @param idNumber        The ID for the Account
     * @param initialDeposit  The initial deposit
     * @param limit           The overdraft limit
     */
    public OverdraftAccount(int idNumber, 
                            double initialDeposit, double limit) 
    {
        balance = 0.0;
        
        id = idNumber;
        if (initialDeposit > 0) balance = initialDeposit;
        
        overdraftLimit = 0.0;
        if (limit > 0.0) overdraftLimit = limit;
    }

    /**
     * Determine the maximum amount that can be withdrawn
     *
     * Note: This method overrides amountAvailable() in Account.
     * This method is called by the method withdraw() which
     * is defined in Account.
     *
     * @return The size of the maximum possible withdrawal
     */
    public double amountAvailable() {

        return (balance+overdraftLimit);
    }
}
        
A More Complicated Example (cont.)
javaexamples/oopbasics/banking/Driver.java
/**
 * An example that uses an OverdraftAccount object
 *
 * @version 1.0
 * @author  Prof. David Bernstein, James Madison University
 */
public class Driver
{
    /**
     * The entry point of the application
     *
     * @param args   The command line arguments
     */
    public static void main(String[] args)
    {
        double            amount;
        boolean           ok;
        OverdraftAccount  billSmith;


        billSmith = new OverdraftAccount(1001, 10000.00,5000.00);
        
        System.out.println("Account "+billSmith.getID()+
                           ": Opened with "+
                           "maximum withdrawl of "+
                           billSmith.amountAvailable());
        
        
        amount = 5000.00;
        ok = billSmith.deposit(amount);
        if (ok)
        {
            System.out.println("Account "+billSmith.getID()+
                               ": Deposit of "+
                               amount);
        } 
        else
        {
            
            System.out.println("Account "+billSmith.getID()+
                               ": Unable to "+
                               "make deposit of "+amount);
        }
        

        amount = 19000.00;
        ok = billSmith.withdraw(amount);
        if (ok)
        {
            System.out.println("Account "+billSmith.getID()+
                               ": Withdrawal of "+amount);
        } 
        else
        {
            System.out.println("Account "+billSmith.getID()+
                               ": Unable to "+
                               "make withdrawal of "+amount);
        }
    }
}
        
A More Complicated Example (cont.)

What Memory Might Look Like After Constructing The OverdraftAccount

images/JavaMemoryModel_AccountExample_AfterConstruction.png
A More Complicated Example (cont.)

What Memory Might Look Like After The Deposit

images/JavaMemoryModel_AccountExample_AfterDeposit.png
A More Complicated Example (cont.)

What Memory Might Look Like After The Withdrawal

images/JavaMemoryModel_AccountExample_AfterWithdrawal.png
Gaining Experience with More Complicated Situations
Static and Dynamic Binding
Polymorphism, Overloading, and Objects as Parameters
Polymorphism, Overloading, and Objects as Parameters (cont.)
Polymorphism, Overloading, and Objects as Parameters (cont.)