Using Interface variables

Viewed 49338

I'm still trying to get a better understanding of Interfaces. I know about what they are and how to implement them in classes.

What I don't understand is when you create a variable that is of one of your Interface types:

IMyInterface somevariable;

Why would you do this? I don't understand how IMyInterface can be used like a class...for example to call methods, so:

somevariable.CallSomeMethod();

Why would you use an IMyInterface variable to do this?

12 Answers

You are not creating an instance of the interface - you are creating an instance of something that implements the interface.

The point of the interface is that it guarantees that what ever implements it will provide the methods declared within it.

So now, using your example, you could have:

MyNiftyClass : IMyInterface
{
    public void CallSomeMethod()
    {
        //Do something nifty
    }
}

MyOddClass : IMyInterface
{
    public void CallSomeMethod()
    {
        //Do something odd
    }
}

And now you have:

IMyInterface nifty = new MyNiftyClass()
IMyInterface odd = new MyOddClass()

Calling the CallSomeMethod method will now do either something nifty or something odd, and this becomes particulary useful when you are passing in using IMyInterface as the type.

public void ThisMethodShowsHowItWorks(IMyInterface someObject)
{
    someObject.CallSomeMethod();
}

Now, depending on whether you call the above method with a nifty or an odd class, you get different behaviour.

public void AnotherClass()
{
    IMyInterface nifty = new MyNiftyClass()
    IMyInterface odd = new MyOddClass()

    // Pass in the nifty class to do something nifty
    this.ThisMethodShowsHowItWorks(nifty);

    // Pass in the odd class to do something odd
    this.ThisMethodShowsHowItWorks(odd);

}

EDIT

This addresses what I think your intended question is - Why would you declare a variable to be of an interface type?

That is, why use:

IMyInterface foo = new MyConcreteClass();

in preference to:

MyConcreteClass foo = new MyConcreteClass();

Hopefully it is clear why you would use the interface when declaring a method signature, but that leaves the question about locally scoped variables:

public void AMethod()
{
    // Why use this?
    IMyInterface foo = new MyConcreteClass();

    // Why not use this?
    MyConcreteClass bar = new MyConcreteClass();
}

Usually there is no technical reason why the interface is preferred. I usually use the interface because:

  • I typically inject dependencies so the polymorphism is needed
  • Using the interface clearly states my intent to only use members of the interface

The one place where you would technically need the interface is where you are utilising the polymorphism, such as creating your variable using a factory or (as I say above) using dependency injection.

Borrowing an example from itowlson, using concrete declaration you could not do this:

public void AMethod(string input)
{               
    IMyInterface foo;

    if (input == "nifty")
    {
        foo = new MyNiftyClass();
    }
    else
    {
        foo = new MyOddClass();
    }
    foo.CallSomeMethod();
}

Because this:

public void ReadItemsList(List<string> items);
public void ReadItemsArray(string[] items);

can become this:

public void ReadItems(IEnumerable<string> items);

Edit

Think of it like this:

You have to be able to do this.

rather than:

You have to be this.

Essentially this is a contract between the method and it's callers.

Lets say you have class Boat, Car, Truck, Plane.

These all share a common method TakeMeThere(string destination)

You would have an interface:

public interface ITransportation
{
    public void TakeMeThere(string destination);
}

then your class:

public class Boat : ITransportation
{
   public void TakeMeThere(string destination) // From ITransportation
   {
       Console.WriteLine("Going to " + destination);
   }
}

What you're saying here, is that my class Boat will do everything ITransportation has told me too.

And then when you want to make software for a transport company. You could have a method

Void ProvideServiceForClient(ITransportation transportationMethod, string whereTheyWantToGo)
{
      transportationMethod.TakeMeThere(whereTheyWantToGo); // Cause ITransportation has this method
}

So it doesn't matter which type of transportation they want, because we know it can TakeMeThere

An interface is used so you do not need to worry about what class implements the interface. An example of this being useful is when you have a factory method that returns a concrete implementation that may be different depending on the environment you are running in. It also allows an API designer to define the API while allowing 3rd parties to implement the API in any way they see fit. Sun does this with it's cryptographic API's for Java.

public interface Foo {

}

public class FooFactory {
    public static Foo getInstance() {
        if(os == 'Windows') return new WinFoo();
        else if(os == 'OS X') return new MacFoo();
        else return new GenricFoo();
    }
}

Your code that uses the factory only needs to know about Foo, not any of the specific implementations.

Using interface variables is the ONLY way to allow handler methods to be written which can accept data from objects that have different base classes.

This is about as clear as anyone is going to get.

The purpose of the Interface is to define a contract between several objects, independent of specific implementation.

So you would usually use it when you have an Intrace ISomething, and a specific implementation

class Something : ISomething

So the Interface varialbe would come to use when you instantiate a contract:

ISomething myObj = new Something();
myObj.SomeFunc();

You should also read interface C#

Update:

I will explaing the logic of using an Interface for the variable and not the class itself by a (real life) example:

I have a generic repositor interace:

Interface IRepository {
    void Create();
    void Update();
}

And i have 2 seperate implementations:

class RepositoryFile : interface IRepository {}
class RepositoryDB : interface IRepository {}

Each class has an entirely different internal implementation.

Now i have another object, a Logger, that uses an already instansiated repository to do his writing. This object, doesn't care how the Repository is implemented, so he just implements:

void WriteLog(string Log, IRepository oRep);

BTW, this can also be implemented by using standard classes inheritance. But the difference between using interfaces and classes inheritance is another discussion.

For a slightly more details discussion on the difference between abstract classes and interfaces see here.

Say, for example, you have two classes: Book and Newspaper. You can read each of these, but it wouldn't really make sense for these two to inherit from a common superclass. So they will both implement the IReadable interface:

public interface IReadable
{
    public void Read();
}

Now say you're writing an application that will read books and newspapers for the user. The user can select a book or newspaper from a list, and that item will be read to the user.

The method in your application that reads to the user will take this Book or Newspaper as a parameter. This might look like this in code:

public static void ReadItem(IReadable item)
{
    item.Read();
}

Since the parameter is an IReadable, we know that the object has the method Read(), thus we call it to read it to the user. It doesn't matter whether this is a Book, Newspaper, or anything else that implements IReadable. The individual classes implement exactly how each item will be read by implementing the Read() method, since it will most likely be different for the different classes.

Book's Read() might look like this:

public void Read()
{
    this.Open();
    this.TurnToPage(1);
    while(!this.AtLastPage)
    {
        ReadText(this.CurrentPage.Text);
        this.TurnPage();
    }
    this.Close();
}

Newspaper's Read() would likely be a little different:

public void Read()
{
    while(!this.OnBackPage)
    {
        foreach(Article article in this.CurrentPage.Articles)
        {
            ReadText(article.Text);
        }
    }
}

The point is that the object contained by a variable that is an interface type is guaranteed to have a specific set of methods on it, even if the possible classes of the object are not related in any other way. This allows you to write code that will apply to a variety of classes that have common operations that can be performed on them.

This is not specific to C#,so i recommend to move to some othere flag. for your question, the main reason why we opt for interface is to provide a protocol between two components(can be a dll,jar or any othere component). Please refer below

 public class TestClass
    {
        static void Main()
        {
            IMyInterface ob1, obj2;
            ob1 = getIMyInterfaceObj();
            obj2 = getIMyInterfaceObj();
            Console.WriteLine(ob1.CallSomeMethod());
            Console.WriteLine(obj2.CallSomeMethod());
            Console.ReadLine();

        }

        private static bool isfirstTime = true;
        private static IMyInterface getIMyInterfaceObj()
        {
            if (isfirstTime)
            {
                isfirstTime = false;
                return new ImplementingClass1();
            }
            else
            {
                return new ImplementingClass2();
            }
        }
    }
    public class ImplementingClass1 : IMyInterface
    {
        public ImplementingClass1()
        {

        }


        #region IMyInterface Members

        public bool CallSomeMethod()
        {
            return true;
        }

        #endregion
    }

    public class ImplementingClass2 : IMyInterface
    {
        public ImplementingClass2()
        {

        }
        #region IMyInterface Members

        public bool CallSomeMethod()
        {
            return false;
        }

        #endregion
    }
    public interface IMyInterface
    {
        bool CallSomeMethod();

    }

Here the main method does not know about the classes still it is able to get different behaviour using the interface.

This is a fundamental concept in object-oriented programming -- polymorphism. (wikipedia)

The short answer is that by using the interface in Class A, you can give Class A any implementation of IMyInterface.

This is also a form of loose coupling (wikipedia) -- where you have many classes, but they do not rely explicitly on one another -- only on an abstract notion of the set of properties and methods that they provide (the interface).

Related