An interface is a specification for a role that an object can play.  If I write a class that implements a specific interface, my class is saying, "I can fulfill the role of one of those."

Here's a tiny code example:

public interface VideoPlayer {
    void playVideo(String clipName);
}

public class VCR implements VideoPlayer {
    public void playVideo(String clipName) {
        // Do the things that VCR does to play the clip,
        // like cue up the tape, start the tape, eject it
    }
}

The interface VideoPlayer specifies what a class has to provide if it is to play the role of a VideoPlayer.  The class must provide a method to playVideo.  The class VCR, by implementing the interface, is taking on the ability to play the role of a VideoPlayer.  It provides its own specific implementation of the playVideo method.

An abstract class provides a basic implementation that other classes can build upon to create an eventual full implementation.  Abstract classes work best when you can implement a high level policy in the base class, and provide successive refinements to that policy in the derived classes.

Here's a code example:

public abstract class VideoDevice implements VideoPlayer {
    public final void playVideo(String clipName) {
        cueUpClip(clipName);
        playClip();
        recueClip();
    }
    protected abstract void cueUpClip(String clipName);
    protected abstract void playClip();
    protected abstract void recueClip();
}

Note how a VideoDevice implements the VideoPlayer interface so it can play the role of a VideoPlayer.  The playVideo method implements a high level policy for playing video.  It cues up the clip to get it ready, plays the clip, and then recues the clip to put it away.  But it doesn't know anything about how specifically to do these three things.  The details depend on the specific type of video device, such as a hard disk based video player, or VCR, or whatever.  So, those methods are declared abstract which says that the specific derived classes have to provide those details.  The playVideo function is declared final to indicate that we don't want the high level policy to be changed by the derived classes.

More code:

public class VCR extends VideoDevice {
    protected void cueUpClip(String clipName) {
        // Move the tape to the proper time code
    }
    protected void playClip() {
        // Start the tape rolling
    }
    protected void recueClip() {
        // Rewind and eject the tape
    }
}

The VCR class provides a specific implementation of a VideoDevice.  It provides the details that were left out of the base VideoDevice class.  Because it extends the VideoDevice class, it also can be used anywhere we want to use a VideoPlayer interface.
 
More code still:

public class VideoTest {
    public static void main(String[] args) {
        VideoPlayer vp = new VCR();
        vp.playVideo("CIS at CCSF Rocks!");
    }
}

This test class shows how we can create a new specific video device, but use it as a generic VideoPlayer role.  We don't have to create the VCR directly here; in fact, usually we won't.  We would probably call some other factory function that does something like read a property file and create the correct specific device to match our configuration.

There you go.  If this leaves you scratching your head, then I recommend a bit of study.  Go read a good Java book, like the Java Tutorial, etc.  (There're plenty of them).  Then go read an object-oriented book, like Booch's.  Then come back and think about these comments some more.

Hope that helps...

- Paul -

File:  AbsClsVsIfx.rtf