Yet another article from the archives. Hope it’s useful.


There is a common Object Oriented axiom that says “Program to the Interface and not to the Implementation”. But what does that mean and why is it useful?

Concrete Shoes

Let’s say that we have a class that calculates the number of Strings that begin with S in a list:

class Begins {
    public static int calcBeginsWithS(ArrayList words) {
        Iterator iter = words.iterator();
        int answer = 0;
        while(iter.hasNext()) {
            String word = (String) iter.next();
            if(word.startsWith("S")) {
                answer++;
            }
        }
        return answer;
    }
}

This function works great as long as we’re only working with ArrayList . But an ArrayList is a concrete class; it’s an implementation of the List interface. There’s nothing in our function that specifically requires using ArrayList and so we’ve crippled what we can do to this class and how it can be used. We’ve prevented ourselves from using this in a number of other cases for no real reason.

Talk to the Interface

Someone may want to call this function with a String[] , but won’t be able to until they get that String[] into an ArrayList. But that’s an extra object you have to create, along with shoving all of the String objects into it, that you’ll just throw away afterwards. But if we change our method to accept List instead:

public static int calcBeginsWithS(List words)

and we have a String[] words , we can call it like this:

int count = Begins.calcBeginsWithS(Arrays.asList(words));

We might also need to update legacy code that uses Vector . (Remember those!) Sun has discouraged the use of Vector , but they have retrofitted the List interface onto it. If your function accepts List instead of ArrayList , you could use it with legacy code that uses Vector too.

But why stop there? If you used:

public static int calcBeginsWithS(Collection words)

You can now use this method with Set and Queue and Stack and it will still work. We’ve made the function support every Collection type in the language and it really didn’t cost us a thing. I’ve personally run into libraries a number of times that only supported List but, with one simple interface change, could have supported the Set that I needed to use with it.

So, when you code something, be sure to ask yourself “Do I really need to code this to a concrete class, or can I use an interface instead?” Walk up that interface tree and see what’s the highest level interface your code can support. You may be able to make your code more powerful by just changing a single word.