Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 5 of 6
As I mentioned at the beginning of this article, it took me a long time to get the point of interfaces. The epiphany finally came when I recognized that separation interface and implementation is one of the primary ideas behind Java in general. The Java virtual machine (JVM), for example, is an abstract computer that defines the way your program "interfaces" with the underlying real computer. A JVM that runs on Windows is one implementation of that abstract computer. A JVM that runs on the Macintosh is another. A JVM that runs on your wristwatch is yet another.
Likewise, the Java APIs are designed not to give you access to specific capabilities of particular computers and operating systems, but define abstract interfaces through which your programs talks to the underlying concrete computer and operating system, whatever it is. Swing, for example, provides an interface through which your Java program can create graphical user interfaces on whatever platform happens to be underneath. You can even use Swing to create user-interfaces on your wristwatch, so long as someone has done the work to implement Swing on your wristwatch.
Separation of interface and implementation is central to Java's spirit, and the Java interface construct enables you to achieve this separation in your designs. Two major activities of any software system design are identifying parts (the subsystems within a program or system of programs) and specifying the interfaces between the parts. In designing a Java-based system, you should use Java interfaces to represent abstract interfaces -- the ways in which the parts will interact with each other.
So this is how I ended up thinking about Java's interfaces: as the preferred means of communicating with the parts of your
program that represent abstractions that may have several implementations. For example, two parts of a program I describe
in my September Design Techniques installment, "The Event Generator Idiom", were TelephoneListener and Telephone. In this design, I decided that the "telephone listener" represented an abstraction that could have multiple implementations,
but that Telephone did not. Thus, I made Telephone a class that didn't implement any interfaces, and defined TelephoneListener as an interface. Telephone, an event source, passed events to (communicated with) listeners through the TelephoneListener interface.
I see interfaces as a fundamental tool for achieving flexibility in the design of Java-based systems. Any class can provide an implementation of an interface. As long as you don't change the interface itself, you can make all kind of changes to the implementing classes, or plug in new classes, without impacting code that depends only on the interface. Thus, if you have a subsystem that represents an abstraction that may have multiple implementations, whether the subsystem is a single object, a group of objects, an entire Java applet or application, you should define Java interfaces through which the rest of the world communicates with that subsystem. When you use interfaces in this way, you decouple the parts of your system from each other and generate code that is more flexible: more easily changed, extended, and customized.