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?