JMU
Interfaces
With Examples in Java


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu


Basics
Interfaces vs. Classes
Interfaces vs. Abstract Classes
UML
Java Details
An Example
An Example (cont.)

The Interface

javaexamples/oopbasics/interfaces/Ordered.java
/**
 * The requirements of objects that can be ordered.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public interface Ordered
{
    /**
     * Compare this object to the given object. Return -1 if this
     * is "less than" other, 0 if they are "equal", and 1 if this 
     * is "greater than" other.
     *
     * @return -1, 0, or 1 as appropriate
     */
    public abstract int compareTo(Ordered other);
}
        
An Example (cont.)

A Class that Implements the Interface

javaexamples/oopbasics/interfaces/Person.java
/**
 * A simple encapsulation of a Person.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class Person implements Ordered
{
    private int    age;    
    private String name;

    /**
     * Constructor.
     *
     * @param name  The name
     * @param age   The age
     */
    public Person(String name, int age)
    {
        this.name = name;
        this.age  = age;
    }

    /**
     * Compare the Person to the given object based on age. Return -1
     * if this is "less than" other, 0 if they are "equal", and 1 if
     * this is "greater than" other. (Required by Ordered)
     *
     * @param other  The object to compare to
     * @return -1, 0, or 1 as appropriate
     */
    public int compareTo(Ordered other)
    {
        Person   otherPerson;

        // This typecast is dangerous because, in principal, this
        // method could be passed any object that implements the
        // Ordered interface. This can be fixed using a
        // parameterized interface (as discussed later).
        otherPerson = (Person)other;

        if       (this.age  < otherPerson.age) return -1;
        else if  (this.age == otherPerson.age) return  0;
        else                                   return  1;
    }

    /**
     * Get the age.
     *
     * @return  The age
     */
    public int getAge()
    {
        return age;
    }

    /**
     * Get the name.
     *
     * @return  The name
     */
    public String getName()
    {
        return name;
    }
}
        
An Example (cont.)

The min()/max() Methods

javaexamples/oopbasics/interfaces/Statistics.java
/**
 * A utility class for calculating descriptive statistics.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class Statistics
{
    /**
     * Find the maximum of some data points.
     *
     * @param data  The data points
     */
    public static Ordered max(Ordered... data)
    {
        Ordered max;

        if (data == null || data.length == 0) 
            throw new IllegalArgumentException();

        if (data.length == 1) return data[0];
        
        max = data[0];        
        for (int i=1; i<data.length; i++)
        {
            if (data[i].compareTo(max) > 0) max = data[i];
        }

        return max;
    }


    /**
     * Find the minimum of some data points.
     *
     * @param data  The data points
     */
    public static Ordered min(Ordered... data)
    {
        Ordered min;

        if (data == null || data.length == 0) 
            throw new IllegalArgumentException();

        if (data.length == 1) return data[0];
        
        min = data[0];        
        for (int i=1; i<data.length; i++)
        {
            if (data[i].compareTo(min) < 0) min = data[i];
        }

        return min;
    }
}
        
An Example (cont.)

An Application

javaexamples/oopbasics/interfaces/PersonDriver.java
/**
 * An example that illustrates the use of interfaces.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class PersonDriver
{
    /**
     * The entry point of the application.
     *
     * @param args  The command line arguments (ignored)
     */
    public static void main(String[] args)
    {
        Person  bart, lisa, maggie, oldest;
        

        bart   = new Person("Bart Simpson",  10);
        lisa   = new Person("Lisa Simpson",   8);
        maggie = new Person("Maggie Simpson", 1);

        oldest = (Person)Statistics.max(bart, lisa, maggie);
        System.out.printf("%s is the oldest at %d", 
                          oldest.getName(), oldest.getAge());
    }
    
}
        
Design Considerations
Design Considerations (cont.)
A Larger Example
A Larger Example (cont.)

The Interface

javaexamples/oopbasics/emergency2/Prioritized.java
/**
 * The requirements of Prioritized objects
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public interface Prioritized
{

    /**
     * Return the priority of this Object.
     *
     * @return  The priority
     */
    public abstract int getPriority();
}
        
A Larger Example (cont.)

The EmergencyMessage Base Class Revisited

javaexamples/oopbasics/emergency2/EmergencyMessage.java
/**
 * A message containing emergency information.
 *
 * This version implements the Prioritized interface.
 * 
 * @author  Prof. David Bernstein, James Madison University
 * @version 2.0
 */
public class EmergencyMessage implements Prioritized
{
    private int        priority;   // Note: These attributes are private
    private String     message;    //       not protected.


    /**
     * Explicit Value Constructor.
     *
     * @param message   The text of the mesage
     */
    public EmergencyMessage(String message)
    {
        this.message = message;
    }

    /**
     * Return the text of this message.
     *
     * @return   The text of the message
     */
    public String getMessage()
    {
        return message;
    }

    /**
     * Return the priority of this message (required by Prioritized).
     *
     * @return   The priority of the message
     */
    public int getPriority()
    {
        return priority;
    }

    /**
     * Set the priority of this message.
     *
     * @param priority   The priority of the message
     */
    public void setPriority(int priority)
    {
        if      (priority <  0) this.priority =  0;
        else if (priority > 10) this.priority = 10;
        else                    this.priority = priority;
    }
}






        
A Larger Example (cont.)

The Alert Derived Class Revisited

javaexamples/oopbasics/emergency2/Alert.java
/**
 * A message containing normal emergency information and a
 * supplemental alert.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class Alert extends EmergencyMessage
{
    private String supplement;


    /**
     * Explicit Value Constructor.
     *
     * @param message      The main mesage
     * @param supplement   The supplemental information
     */
    public Alert(String message, String supplement)
    {
        super(message);
        this.supplement = supplement;
    }

    /**
     * Return the supplemental information.
     *
     * @return   The supplemental information
     */
    public String getSupplement()
    {
        return supplement;
    }
}


        
A Larger Example (cont.)

A Prioritized that does not Specialize EmergencyMessage

javaexamples/oopbasics/emergency2/AccidentReport.java
/**
 * An accident report
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class AccidentReport implements Prioritized
{
    private int     size;
    private String  type;


    /**
     * Explicit Value Constructor.
     *
     * @param type   The type of accident
     * @param size   The number of vehicles involved
     */
    public AccidentReport(String type, int size)
    {
        this.type = type;
        this.size = size;
    }

    /**
     * Return the priority of this AccidentReport (required by
     * Prioritized).
     *
     * @return   The priority of this AccidentReport
     */
    public int getPriority()
    {
        int priority;


        if (size > 3) priority = 5;
        else if (size > 5) priority = 10;
        else if (type.equals("HEAD ON")) priority = 8;
        else priority = 3;

        return priority;
    }

    /**
     * Set the size of the accident.
     *
     * @param size   The number of vehicles involved
     */
    public void setSize(int size)
    {
        this.size = size;
    }
}
        
A Larger Example (cont.)

An Application

Note that this application uses an array of Prioritized objects (which can contain EmergencyMessage objects, Alert objects, and AccidentReport objects).

javaexamples/oopbasics/emergency2/Driver.java
/**
 * An example that uses interfaces and derived classes
 *
 * @version 1.0
 * @author  Prof. David Bernstein, James Madison University
 */
public class Driver
{

    public static void main(String[] args)
    {
        AccidentReport       accident1, accident2;
        int                  k;
        Prioritized[]        priorities;
        Alert                alert;
        EmergencyMessage     message;
        


        priorities = new Prioritized[4];

        message = new EmergencyMessage("Congestion on I81 north!");
        priorities[0] = message;

        alert = new Alert("Route 11 Closed in Both Directions",
                          "Use I81 Instead");
        alert.setPriority(4);
        priorities[1] = alert;


        accident1 = new AccidentReport("FENDER BENDER", 2);
        priorities[2] = accident1;

        accident2 = new AccidentReport("HEAD ON", 2);
        priorities[3] = accident2;


        k = countHighPriorityItems(priorities);
        System.out.println("\n\n\n");
        if (k == 1) 
        {
          System.out.println("1 item is crucial!");

        } else {

          System.out.println(k+" items are crucial!");
        }


        accident1.setSize(4);
        k = countHighPriorityItems(priorities);
        System.out.println("\n\n\n");
        if (k == 1) 
        {
          System.out.println("1 item is crucial!");

        } else {

          System.out.println(k+" items are crucial!");
        }



    }


    /**
     * Determine the number of high priorty items
     */
    public static int countHighPriorityItems(
                           Prioritized[] items)
    {
        int i, count;

        count = 0;
        for (i=0; i < items.length; i++) 
        {
            if (items[i].getPriority() >= 5) count++;
        }
        return count;
    }
}
        
Implementing Multiple Interfaces
Specializing Interfaces
Specializing Interfaces (cont.)
Constructors in Interfaces
Uses for Interfaces
Base/Derived Classes and Interfaces
Interfaces in the Java API
Returning to the Larger Example

Suppose we want to be able to find the AccidentReport involving the largest number of vehicles.

javaexamples/oopbasics/emergency3/AccidentReport.java
/**
 * An accident report.
 *
 * This version implements the Ordered interface
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 2.0
 */

public class AccidentReport implements Ordered, Prioritized
{
    private int     size;
    private String  type;


    /**
     * Explicit Value Constructor.
     *
     * @param type   The type of accident
     * @param size   The number of vehicles involved
     */
    public AccidentReport(String type, int size)
    {
        this.type = type;
        this.size = size;
    }

    /**
     * Compares this Ordered Object with the given Ordered Object 
     * (required by Ordered).
     *
     * @param other   The Object to compare
     * @return -1/0/1 if this is less than/equal to/before other
     */
    public int compareTo(Ordered other)
    {
        // This is a risky typecast. We will discuss ways
        // of correcting it later.
        AccidentReport ar = (AccidentReport)other;
        
        if      (this.size == ar.size) return  0;
        else if (this.size  < ar.size) return -1;
        else                           return  1;
    }

    /**
     * Return the priority of this AccidentReport (required by
     * Prioritized).
     *
     * @return   The priority of this AccidentReport
     */
    public int getPriority()
    {
        int priority;


        if (size > 3) priority = 5;
        else if (size > 5) priority = 10;
        else if (type.equals("HEAD ON")) priority = 8;
        else priority = 3;

        return priority;
    }

    /**
     * Set the size of the accident.
     *
     * @param size   The number of vehicles involved
     */
    public void setSize(int size)
    {
        this.size = size;
    }

    /**
     * Get a String representation of this AccidentReport.
     *
     * @return  The String representation
     */
    public String toString()
    {
        return type + "\t" + size;
    }
    
}
        
Returning to the Larger Example (cont.)

An Application

javaexamples/oopbasics/emergency3/Driver.java
/**
 * An example that uses the Ordered interface.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class Driver
{

    public static void main(String[] args)
    {
        AccidentReport[]     reports;
        AccidentReport       largest;        
        
        reports    = new AccidentReport[3];
        reports[0] = new AccidentReport("FENDER BENDER", 2);
        reports[1] = new AccidentReport("OVERTURNED TRACTOR-TRAILER", 8);
        reports[2] = new AccidentReport("HEAD ON", 2);

        // Note that the max() returns an Ordered which must be
        // typecast as an AccidentReport if any methods in that
        // class are to be used
        largest = (AccidentReport)Statistics.max(reports);

        System.out.printf("%s\t(%d)\n", 
                          largest.toString(), largest.getPriority());
    }
}
        
Returning to the Larger Example (cont.)