Categories
interface language-agnostic oop

What does it mean to “program to an interface”?

889

I have seen this mentioned a few times and I am not clear on what it means. When and why would you do this?

I know what interfaces do, but the fact I am not clear on this makes me think I am missing out on using them correctly.

Is it just so if you were to do:

IInterface classRef = new ObjectWhatever()

You could use any class that implements IInterface? When would you need to do that? The only thing I can think of is if you have a method and you are unsure of what object will be passed except for it implementing IInterface. I cannot think how often you would need to do that.

Also, how could you write a method that takes in an object that implements an interface? Is that possible?

14

  • 4

    If you can remember and your program needs to be optimal, just before compilation you may wish to swap the Interface declaration for the actual implementation. As using an interface adds a level of indirection which gives a performance hit. Distribute your code programmed to interfaces though…

    Dec 21, 2008 at 4:21

  • 24

    @Ande Turner: that’s poor advice. 1). “your program needs to be optimal” is not a good reason for swapping out interfaces! Then you say “Distribute your code programmed to interfaces though…” so you are advising that given requirement (1) you then release sub-optimal code?!?

    Dec 21, 2008 at 4:26

  • 80

    Most of the answers here aren’t quite right. It doesn’t mean or even imply “use the interface keyword” at all. An interface is a spec of how to use something–synonymous with the contract (look it up). Separate from that is the implementation, which is how that contract is fulfilled. Program against only the guarantees of the method / type so that, when the method / type is changed in a way that still obeys the contract, it does not break the code using it.

    – jyoungdev

    Apr 27, 2012 at 16:34

  • 2

    @apollodude217 that is actually the best answer on the entire page. At least for the question in the title, since there are at least 3 quite different questions here…

    May 2, 2012 at 8:36

  • 7

    The fundemental problem with questions like this is that it assumes that “programming to an interface” means “wrap everything in an abstract interface”, which is silly if you consider the term predates the concept of Java style abstract interfaces.

    Jul 19, 2012 at 19:37

1783

There are some wonderful answers on here to this questions that get into all sorts of great detail about interfaces and loosely coupling code, inversion of control and so on. There are some fairly heady discussions, so I’d like to take the opportunity to break things down a bit for understanding why an interface is useful.

When I first started getting exposed to interfaces, I too was confused about their relevance. I didn’t understand why you needed them. If we’re using a language like Java or C#, we already have inheritance and I viewed interfaces as a weaker form of inheritance and thought, “why bother?” In a sense I was right, you can think of interfaces as sort of a weak form of inheritance, but beyond that I finally understood their use as a language construct by thinking of them as a means of classifying common traits or behaviors that were exhibited by potentially many non-related classes of objects.

For example — say you have a SIM game and have the following classes:

class HouseFly inherits Insect {
    void FlyAroundYourHead(){}
    void LandOnThings(){}
}

class Telemarketer inherits Person {
    void CallDuringDinner(){}
    void ContinueTalkingWhenYouSayNo(){}
}

Clearly, these two objects have nothing in common in terms of direct inheritance. But, you could say they are both annoying.

Let’s say our game needs to have some sort of random thing that annoys the game player when they eat dinner. This could be a HouseFly or a Telemarketer or both — but how do you allow for both with a single function? And how do you ask each different type of object to “do their annoying thing” in the same way?

The key to realize is that both a Telemarketer and HouseFly share a common loosely interpreted behavior even though they are nothing alike in terms of modeling them. So, let’s make an interface that both can implement:

interface IPest {
    void BeAnnoying();
}

class HouseFly inherits Insect implements IPest {
    void FlyAroundYourHead(){}
    void LandOnThings(){}

    void BeAnnoying() {
        FlyAroundYourHead();
        LandOnThings();
    }
}

class Telemarketer inherits Person implements IPest {
    void CallDuringDinner(){}
    void ContinueTalkingWhenYouSayNo(){}

    void BeAnnoying() {
        CallDuringDinner();
        ContinueTalkingWhenYouSayNo();
    }
}

We now have two classes that can each be annoying in their own way. And they do not need to derive from the same base class and share common inherent characteristics — they simply need to satisfy the contract of IPest — that contract is simple. You just have to BeAnnoying. In this regard, we can model the following:

class DiningRoom {

    DiningRoom(Person[] diningPeople, IPest[] pests) { ... }

    void ServeDinner() {
        when diningPeople are eating,

        foreach pest in pests
        pest.BeAnnoying();
    }
}

Here we have a dining room that accepts a number of diners and a number of pests — note the use of the interface. This means that in our little world, a member of the pests array could actually be a Telemarketer object or a HouseFly object.

The ServeDinner method is called when dinner is served and our people in the dining room are supposed to eat. In our little game, that’s when our pests do their work — each pest is instructed to be annoying by way of the IPest interface. In this way, we can easily have both Telemarketers and HouseFlys be annoying in each of their own ways — we care only that we have something in the DiningRoom object that is a pest, we don’t really care what it is and they could have nothing in common with other.

This very contrived pseudo-code example (that dragged on a lot longer than I anticipated) is simply meant to illustrate the kind of thing that finally turned the light on for me in terms of when we might use an interface. I apologize in advance for the silliness of the example, but hope that it helps in your understanding. And, to be sure, the other posted answers you’ve received here really cover the gamut of the use of interfaces today in design patterns and development methodologies.

20

  • 4

    Another thing to consider is that in some cases it might be useful to have an interface for things that “might” be annoying, and have a varierty of objects implement BeAnnoying as a no-op; this interface may exist in place of, or in addition to, the interface for things that are annoying (if both interfaces exist, the “things that are annoying” interface should inherit from the “things that might be annoying” interface). The disadvantage of using such interfaces is that implementations may get burdened with implementing an “annoying” number of stub methods. The advantage is that…

    – supercat

    Jul 20, 2012 at 14:39

  • 4

    The methods are not intended to represent abstract methods — their implementation is irrelevant to the question which focused on interfaces.

    Feb 18, 2014 at 19:06

  • 44

    Encapsulating behaviors, such as IPest is known as the strategy pattern just in case anyone is interested on following up with more material on that subject…

    – nckbrz

    Mar 9, 2014 at 19:15

  • 10

    Interestingly, you don’t point out that because the objects in the IPest[] are IPest references, you can call BeAnnoying() because they have that method, while you can’t call other methods without a cast. However, each objects individual BeAnnoying() method will be called.

    May 26, 2015 at 1:16

  • 4

    Very good explanation… I just need to say it here: I never heard of interfaces being some kind of loose inheritance mechanism, but instead I know of inheritance being used as a poor mechanism for defining interfaces (for example, in regular Python you do it all the time).

    Aug 9, 2015 at 15:37


320

The specific example I used to give to students is that they should write

List myList = new ArrayList(); // programming to the List interface

instead of

ArrayList myList = new ArrayList(); // this is bad

These look exactly the same in a short program, but if you go on to use myList 100 times in your program you can start to see a difference. The first declaration ensures that you only call methods on myList that are defined by the List interface (so no ArrayList specific methods). If you’ve programmed to the interface this way, later on you can decide that you really need

List myList = new TreeList();

and you only have to change your code in that one spot. You already know that the rest of your code doesn’t do anything that will be broken by changing the implementation because you programmed to the interface.

The benefits are even more obvious (I think) when you’re talking about method parameters and return values. Take this for example:

public ArrayList doSomething(HashMap map);

That method declaration ties you to two concrete implementations (ArrayList and HashMap). As soon as that method is called from other code, any changes to those types probably mean you’re going to have to change the calling code as well. It would be better to program to the interfaces.

public List doSomething(Map map);

Now it doesn’t matter what kind of List you return, or what kind of Map is passed in as a parameter. Changes that you make inside the doSomething method won’t force you to change the calling code.

3

  • Comments are not for extended discussion; this conversation has been moved to chat.

    – user3956566

    Jan 12, 2019 at 18:51

  • I have a question on the reason you mentioned “The first declaration ensures that you only call methods on myList that are defined by the List interface (so no ArrayList specific methods). If you’ve programmed to the interface this way, later on you can decide that you really need List myList = new TreeList(); and you only have to change your code in that one spot.” Maybe I have misunderstood, I wonder why you need to change ArrayList to TreeList if you want to “ensures that you only call methods on myList “?

    Oct 23, 2019 at 19:25

  • 2

    @user3014901 There are any number of reasons you might want to change the type of list you’re using. One might have better lookup performance, for example. The point is, that if you program to the List interface, it makes it easier to change your code to a different implementation later.

    Oct 24, 2019 at 13:56

86

Programming to an interface is saying, “I need this functionality and I don’t care where it comes from.”

Consider (in Java), the List interface versus the ArrayList and LinkedList concrete classes. If all I care about is that I have a data structure containing multiple data items that I should access via iteration, I’d pick a List (and that’s 99% of the time). If I know that I need constant-time insert/delete from either end of the list, I might pick the LinkedList concrete implementation (or more likely, use the Queue interface). If I know I need random access by index, I’d pick the ArrayList concrete class.

1

  • 1

    totally agree i.e. the independence between what is done vs. how it is done. By partitioning a system along independent components, you end up with a system that it is simple and reusable (see Simple Made Easy by the guy who created Clojure)

    – beluchin

    Dec 29, 2013 at 7:56