Using Interfaces for Code Reuse
Use interface types to make code more reusable
In Chapter 6, we created a DataSet to find the average and maximum of a set of values (numbers)
What if we want to find the average and maximum of a set of BankAccount values?
public class DataSet // Modified for BankAccount objects
{
. . .
public void add(BankAccount x)
{
sum = sum + x.getBalance();
if (count == 0 || maximum.getBalance() < x.getBalance())
maximum = x;
count++;
}
public BankAccount getMaximum()
{
return maximum;
}
private double sum;
private BankAccount maximum;
private int count;
}Or suppose we wanted to find the coin with the highest value among a set of coins. We would need to modify the DataSet class again:
public class DataSet // Modified for Coin objects
{
. . .
public void add(Coin x)
{
sum = sum + x.getValue();
if (count == 0 || maximum.getValue() < x.getValue())
maximum = x;
count++;
}public Coin getMaximum()
{
return maximum;
}
private double sum;
private Coin maximum;
private int count;
}
The mechanics of analyzing the data is the same in all cases; details of measurement differ
Classes could agree on a method getMeasure that obtains the measure to be used in the analysis
We can implement a single reusable DataSet class whose add method looks like this:
sum = sum + x.getMeasure();
if (count == 0 || maximum.getMeasure() < x.getMeasure())
maximum = x;count++;
What is the type of the variable x?
x should refer to any class that has a getMeasure method
In Java, an interface type is used to specify required operations
public interface Measurable
{
double getMeasure();
}
Interface declaration lists all methods (and their signatures) that the interface type requires
Interfaces vs. Classes
An interface type is similar to a class, but there are several important differences:
All methods in an interface type are abstract; they don't have an implementation
All methods in an interface type are automatically public
An interface type does not have instance fields
Generic DataSet for Measurable Objects
public class DataSet
{
. . .
public void add(Measurable x)
{
sum = sum + x.getMeasure();
if (count == 0 || maximum.getMeasure() < x.getMeasure())
maximum = x;
count++;
}
public Measurable getMaximum()
{
return maximum;
}private double sum;
private Measurable maximum;
private int count;
}
Implementing an Interface Type
Use implements keyword to indicate that a class implements an interface type
public class BankAccount implements Measurable
{
public double getMeasure()
{
return balance;
}
// Additional methods and fields
}
A class can implement more than one interface type
Class must define all the methods that are required by all the interfaces it implements
public class Coin implements Measurable
{
public double getMeasure()
{
return value;
}
// Additional methods and fields
}
UML Diagram of DataSet and Related Classes
Interfaces can reduce the coupling between classes
UML notation:
Interfaces are tagged with a "stereotype" indicator Ğinterfaceğ
A dotted arrow with a triangular tip denotes the "is-a" relationship between a class and an interface
A dotted line with an open v-shaped arrow tip denotes the "uses" relationship or dependency
Note that DataSet is decoupled from BankAccount and Coin
Click here for Example of Measurable Interface.
Suppose you want to use the DataSet class to find the Country object with the largest population. What condition must the Country class fulfill?
Answer:
It must implement the
Measurable
interface, and its
getMeasure
method must return the population.
Why can't the add method of the DataSet class have a parameter of type Object?
Answer:
The
Object
class doesn't have a
getMeasure
method,
and the
add
method invokes the
getMeasure
method.