More Features of the Java Language |
In English, an interface is a device or system that unrelated entities use to interact. According to this definition, a remote control is an interface between you and a television set, the English language is an interface between two people, and the protocol of behavior enforced in the military is the interface between people of different ranks. Similarly, a Java interface is a device that unrelated objects use to interact with one another. Java interfaces are probably most analogous to protocols (an agreed-upon behavior). In fact, other object-oriented languages have the functionality of Java's interfaces, but they call their interfaces protocols.A Java interface defines a set of methods but does not implement them. A class that implements the interface agrees to implement all of the methods defined in the interface, thereby agreeing to certain behavior.
Definition: An interface is a named collection of method definitions (without implementations). An interface can also include constant declarations.
Interfaces are best understood through examples, so let's look at a concrete example of an interface and two classes that use it to interact. Then we'll talk more about interfaces in the abstract and clear up some common confusion.
Example: AlarmClock and Sleeper
This example is fairly simple, but it shows you how to create and use an interface. It also gives you some insight as to why you need them and how to decide when to use an interface versus when to use a class or an abstract class.The
AlarmClock
class is a service provider-- it notifies objects after a certain amount of time has elapsed.To get on
AlarmClock
's list of "sleepers," an object must do two things:To satisfy the first requirement, an object calls
- Ask the alarm clock to wake it up.
- Implement the
wakeUp
method.AlarmClock
'sletMeSleepFor
method, which is implemented like this:Ifpublic synchronized boolean letMeSleepFor(Sleeper theSleeper, long time) { int index = findNextSlot(); if (index == NOROOM) { return false; } else { sleepers[index] = theSleeper; sleepFor[index] = time; new AlarmThread(index).start(); return true; } }AlarmClock
has space, then it registers the sleeper, starts a newAlarmThread
for it, and returnstrue
. After the specified amount of time has elapsed theAlarmClock
will calltheSleeper
'swakeUp
method.This leads to the second requirement. An object that wants to use
AlarmClock
must implement thewakeUp
method (so thatAlarmClock
can call it to notify the object after the time has elapsed). But how is this enforced? It's enforced through the data type of the object being registered.The first argument to the
letMeSleepFor
method is the object that wants to get woken up. The data type of this argument isSleeper
, which is the name of this interface:Thepublic interface Sleeper { public void wakeUp(); public long ONE_SECOND = 1000; // in milliseconds public long ONE_MINUTE = 60000; // in milliseconds }Sleeper
interface defines thewakeUp
method but does not implement it. It also defines two useful constants. Classes that implement this interface "inherit" the constants and must implementwakeUp
.Any object that is a
Sleeper
(and can therefore be passed intoletMeSleepFor
) implements this interface. This means it implements all of the methods defined by the interface. Thus aSleeper
object implements thewakeUp
method, thereby satisfyingAlarmClock
's second requirement.For example, check out the following small class that implements the
Sleeper
interface. TheGUIClock
class is an applet that displays the current time and uses anAlarmClock
object to wake it up every minute so that it can update its display:Here's the GUIClock applet running:class GUIClock extends Applet implements Sleeper { . . . public void wakeUp() { repaint(); clock.letMeSleepFor(this, ONE_MINUTE); } }Now that you've seen an interface in action, we'll answer some of the inevitable questions.
Note: Because some old browsers don't support 1.1, the above applet is a 1.0 version (here is the 1.0 code; here's the 1.1 code). To run the 1.1 version of the applet, go toexample-1dot1/GUIClock.html
.Why Can't I Just Use an Abstract Class?
At this point, many programmers wonder how an interface differs from an abstract class. An interface is simply a list of unimplemented, and therefore abstract, methods. Wouldn't the followingSleeper
class do the same thing as theSleeper
interface?No. The two are not equivalent. Ifabstract class Sleeper { public abstract void wakeUp(); }Sleeper
is an abstract class, then all objects that wish to useAlarmClock
must be instances of a class inherited fromSleeper
. However, many objects that wish to useAlarmClock
already have a superclass. For example, theGUIClock
is anApplet
; it must be an applet to run inside a browser. But Java doesn't support multiple inheritance. SoGUIClock
can't be both aSleeper
and anApplet
. Hence, you use an interface instead.This is the practical explanation of the problem. The conceptual explanation is this:
AlarmClock
should not force a class relationship on its users. It doesn't matter what their class is. It simply matters that they implement a specific method.Oh! So Interfaces Provide for Multiple Inheritance?
Often interfaces are touted as an alternative to multiple class inheritance. While interfaces may solve similar problems, interface and multiple class inheritance are quite different animals, in particular:Yet, Java does allow multiple interface inheritance. That is, an interface can have multiple superinterfaces.
- A class inherits only constants from an interface.
- A class cannot inherit method implementations from an interface.
- The interface hierarchy is independent of the class hierarchy. Classes that implement the same interface may or may not be related through the class hierarchy. This is not true for multiple inheritance.
So Tell Me, What Can I Use Interfaces For?
You use an interface to define a protocol of behavior that can be implemented by any class anywhere in the class hierarchy. Interfaces are useful for the following:
- Capturing similarities between unrelated classes without artificially forcing a class relationship
- Declaring methods that one or more classes are expected to implement
- Revealing an object's programming interface without revealing its class. (Objects such as these are called anonymous objects and can be useful when shipping a package of classes to other developers.)
More Features of the Java Language |