tags:

views:

139

answers:

6

In what scenarios would somebody pass (or receive) an interface as a parameter? Is it really a useful thing or just a fancy way of doing something?

+2  A: 

Whenever you need abstraction.

One good example is the IEnumerable<T> and IQueryable<T> interfaces in the .NET Framework. They allow you to write Extension Methods that can be used against List<T>, Dictionary<TKey, TValue>, or even T[].

You could also take Dependency Injection for example. In ASP.NET MVC, it is common to use Repositories for Data Access:

public class MyClassRepository
{
    public MyClass GetById(int id)
    {
        // Some Implementation
    }
}

public class MyController
{
    private MyClassRepository _repo;

    public class MyController() : base(new MyClassRepository()) { }

    public class MyController(MyClassRepository repo) { _repo = repo; }
}

Now, if you want to Mock that Repository for Unit Testing...you're boned. There's no easy way. In comes Interfaces!

public interface IMyClassRepository
{
    public MyClass GetById(int id);
}

public class MyClassRepository : IMyClassRepository
{
    public MyClass GetById(int id)
    {
        // Some Implementation
    }
}

public class MyController
{
    private IMyClassRepository _repo;

    public class MyController() : base(new MyClassRepository()) { }

    public class MyController(IMyClassRepository repo) { _repo = repo; }
}

Now with the introduction of an Interface, we are free to mock IMyClassRepository however we see fit for testing purposes. Usually this involves a simple mock object with specified behavior to product reliable results.

Justin Niessner
+1  A: 

Interfaces are very useful.

They help with decoupling your code - for example, if you use the IList interface and pass that in to your method and use it in your method, you can pass in any collection that implements this interface, whether it is in the BCL or not.

Oded
+15  A: 

It's an extremely useful thing.

Take any of the LINQ extension methods, for instance. They don't care what's passed to them, as long as it implements IEnumerable<T>. The idea is that they can all be applied to anything that you can enumerate over using a foreach loop.

Imagine how pointlessly restrictive it would be if they all required you to pass T[] arrays, or List<T> objects, for example.


Here's just one very trivial illustration. Let's pretend the LINQ extensions don't exist (which is actually a real possibility if I'm using .NET 2.0) and I want to write a Sum method.

I could write it like this:

public static double Sum(List<double> values)
{
    double sum = 0.0;
    foreach (double value in values)
    {
        sum += value;
    }
    return sum;
}

That's all well and good, but notice something here: I wrote the method to take a List<double>, which is a class that has far more functionality than this code depends on. Where does it use Insert? Where does it use RemoveAt? FindAll? Sort? Nope, none of that is required. So is it really necessary that this method get passed a List<double>?

Moreover, say I have a double[]. Theoretically, I should be able to pop that right in as the values parameter, since all I'm doing is enumerating over it using a foreach; but since I've typed values as List<double>, to pass a double[] to my Sum method I'd have to do this:

double sum = Sum(new List<double>(myArray));

That's just a completely unnecessary new object I've constructed simply to call code that really should've been able to handle my original object in the first place.

By writing methods that take interfaces as parameters, you make your code more flexible and more powerful, and you avoid imposing inappropriate restrictions (give me an X, even though I could just as easily do this with a Y) on calling code.

Dan Tao
+1 for **extremely useful**
ck
+1  A: 

One area where interfaces would make good sense is if you are using a design pattern approach.

For instance, the Observer pattern, or the Proxy pattern, the Visitor pattern, and others. You probably could choose not to use an interface, but I'd imagine that you'll quickly decide that the code becomes much cleaner (as in more modular, concerns-separated) than a non-interfaced code. It just helps promote better code, in these situations.

code4life
+4  A: 

The easiest way to remember, is that it's all about programming to the interface, not the implementation. Say for instance, I have a method where I want to do something, e.g.

public void MakeNoise(IAnimal animal)
{
  animal.MakeNoise();
}

I don't care what the specific implementation is, I just know that whatever is passed in, I can call MakeNoise(). I program to an interface, not an implementation.

public class Dog : IAnimal
{
  public void MakeNoise()
  {
    Console.WriteLine("Woof");
  }
}

public class Cat : IAnimal
{
  public void MakeNoise()
  {
    Console.WriteLine("Meow");
  }
}

Interface programming is a core aspect of OOP, you'll find them incredibly useful.

Matthew Abbott
+1 for the very easy-to-understand explaination. Thanks.
Abhi
Because you're programming only to the interface choose their names carefully. INoiseMaker may be more appropriate in this case. That way it will be natural for other classes to implement the interface, i.e. JetPlane, FireCracker, or SmallChild.
Dave M
@Dave M, very good point, interfaces (contracts) should be descriptive of their use. Thanks :)
Matthew Abbott
A: 

Polymorphism!

They help you write code that doesn't discriminate against certain classes just because they don't inherit from a special base class. Your functions will be equal-opportunity executors.

Dr. Wily's Apprentice