|
Interfaces
With Examples in Java |
|
Prof. David Bernstein |
| Computer Science Department |
| bernstdh@jmu.edu |
abstract
modifier) terminated by a ;
/**
* 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);
}
/**
* 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;
}
}
min()/max() Methods/**
* 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 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());
}
}
min() and max()
return the index
/**
* 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();
}
EmergencyMessage Base Class Revisited/**
* 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;
}
}
Alert Derived Class Revisited/**
* 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;
}
}
Prioritized that does not Specialize EmergencyMessage
/**
* 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;
}
}
Note that this application uses an array of Prioritized objects
(which can contain EmergencyMessage objects, Alert
objects, and AccidentReport objects).
/**
* 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;
}
}
B
contains all of the methods in the
interface A (and more)B specialize the
interface A
public interface B extends A {...}
extends and implements?
Alert extends
EmergencyMessage and could implement
one or more interfacesAlert realizes
the Prioritized interface
Suppose we want to be able to find the AccidentReport
involving the largest number of vehicles.
/**
* 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;
}
}
/**
* 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());
}
}
compareTo() method could
use the result of a call to getPriority()
rather than the size of the accidentcompareTo() method could be moved
to the base EmergencyMessage class and the
typecast would be to a Prioritized
and
a compareTo() method would have to be added
to the AccidentReport classPrioritized interface extend the
Ordered interface?compareTo() methods in EmergencyMessage
and AccidentReport? Should specialization be
used to eliminate this code duplication?