Why Use Interfaces?

I’m a bit tipsy at the moment, so hopefully this post goes well.

A question that I like to ask while interviewing individuals is: “why would you want to use an interface?” I get a ton of answers that span the supposed gamut of programming; some are good and some are of course terrible, however I’d like to share some input on what I feel is the importance of interfaces.

Interfaces allow for the application of polymorphism (the ability of an object to exhibit multiple behaviours). In short: more polymorphism = less refactoring in the future when you change code. Less changes to do new things = happier programmers.

Let’s say that your customer/business asks you to write an application that makes a Dog speak. So you code something similar to this:

/// <summary>
/// Represents a Dog.
/// </summary>
public class Dog
{
    /// <summary>
    /// Makes the Dog Speak.
    /// </summary>
    public void Speak()
    {
        Console.WriteLine("Woof!");
    }
}

/// <summary>
/// Makes a Dog Speak.
/// </summary>
/// <param name="dog">The Dog to make Speak.</param>
public static void MakeDogSpeak(Dog dog)
{
    // Sanitize
    if (dog == null)
    {
        return;
    }

    // Make the Dog Speak
    dog.Speak();
}

In this scenario, making the Dog Speak is quite easy:

static void Main(string[] args)
{
    var dog = new Dog();

    MakeDogSpeak(dog);
}

Now imagine that the customer/business changes their mind – which of course never ever happens. They tell you that they have a Cat which can also speak, and that you need to change your program to allow both the Dog and Cat to speak. What a pain in the butt! Now we need to create the Cat class and add another method:

/// <summary>
/// Represents a Cat.
/// </summary>
public class Cat
{
    /// <summary>
    /// Makes the Cat Speak.
    /// </summary>
    public void Speak()
    {
        Console.WriteLine("Meow! (while glaring at you since Cats are evil)");
    }
}

/// <summary>
/// Makes a Cat Speak.
/// </summary>
/// <param name="dog">The Cat to make Speak.</param>
public static void MakeCatSpeak(Cat cat)
{
    // Sanitize
    if (cat == null)
    {
        return;
    }

    // Make the Cat Speak
    cat.Speak();
}

Now, making the Dog and Cat Speak is also quite easy, if a bit cumbersome:

static void Main(string[] args)
{
    var dog = new Dog();

    MakeDogSpeak(dog);

    var cat = new Cat();

    MakeCatSpeak(cat);
}

Are you seeing the tedious trend here? What happens when the customer/business now wants a Horse to speak, and a Lamb to speak, and a Tiger to speak, and even an Elephant to speak? What about a Unicorn or Human or Computer that needs to speak? Creating a method for each of these objects totally sucks and destroys your ability to write efficient OO code. So, what are we to do? Enter interfaces.

Interfaces exist to define a contract for common functionality which can be used in polymorphic ways. Let me repeat that once more to stress importance, interfaces are an important part of OO programming that allows you to capture common functionality and avoid tedious (and unnecessary) code.

Let’s look at the prior examples. We know that we have a Dog and a Cat, and that they both Speak. From this we can analyze and see some common functionality. We realize that we can define a common interface for these objects that encapsulates speaking:

/// <summary>
/// Represents an object that can Speak.
/// </summary>
public interface ICanSpeak
{
    /// <summary>
    /// Makes the object Speak.
    /// </summary>
    void Speak();
}

Let us now update our Dog and Cat such that they implement this interface:

/// <summary>
/// Represents a Dog.
/// </summary>
public class Dog : ICanSpeak
{
    /// <summary>
    /// Makes the Dog Speak.
    /// </summary>
    public void Speak()
    {
        Console.WriteLine("Woof!");
    }
}

/// <summary>
/// Represents a Cat.
/// </summary>
public class Cat : ICanSpeak
{
    /// <summary>
    /// Makes the Cat Speak.
    /// </summary>
    public void Speak()
    {
        Console.WriteLine("Meow! (while glaring at you since Cats are evil)");
    }
}

Finally, let’s take advantage of the polymorphism that this interface now offers and reduce our two speaking methods into one useful method:

/// <summary>
/// Makes something Speak.
/// </summary>
/// <param name="speaker">The Speaker to make Speak.</param>
public static void MakeSomethingSpeak(ICanSpeak speaker)
{
    // Sanitize
    if (speaker == null)
    {
        return;
    }

    // Make the Speaker Speak
    speaker.Speak();
}

Two methods become one. In fact, N methods become one if they implement the common functionality encapsulated in the interface. This means that you can sleep peacefully at night knowing that no matter how many things the customer/business wants to have speak tomorrow, it’s not that hard to update your code to handle it. Finally, let us update our Main which runs the speak commands just to close the example:

static void Main(string[] args)
{
    var dog = new Dog();

    MakeSomethingSpeak(dog);

    var cat = new Cat();

    MakeSomethingSpeak(cat);
}

Now, no matter how many objects are defined that are to speak, we need only the single method as long as those objects implement the appropriate interface.

There are many other benefits to interfaces which we will discuss in future posts. However, I hope that this begins to exhibit the purpose and usefulness of defining interfaces and having types which share common functionality implement them. Cheers!


See also