48

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?

PositiveGuy
  • 46,620
  • 110
  • 305
  • 471

12 Answers12

78

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();
}
David Hall
  • 32,624
  • 10
  • 90
  • 127
  • I still don't get why you would create an IMyInterface variable and not just do for instance MyNiftyClass nifty = MyNiftyClass(). To me yes an interface is an abstract class basically but it has no implementation, it's just a skeleton of required members that subclasses must implement. So how can an instance of IMyInterface hold anything when the implementation are in x,y,z classes that all implement that interface? I don't see why you even need an IMyInterface variable at all to call methods implemented in the subclass itself – PositiveGuy Jan 28 '10 at 03:29
  • "The purpose of the Interface is to define a contract between several objects, independent of specific implementation." Yes I get all this. It's why you need to use IMyInterface var everywhere in subclasses instead of an instance of the subclass itself! – PositiveGuy Jan 28 '10 at 03:31
  • The question is not what an interface is and what it's meant for. I know that. It's why do you use Interface variables – PositiveGuy Jan 28 '10 at 03:32
  • 3
    look at the signature of public void ThisMethodShowsHowItWorks(IMyInterface someObject) That parameter is a variable of type IMyInterface. That is why you use interface variables - they can take any that implements the variable – David Hall Jan 28 '10 at 03:40
  • 2
    Also, you need to keep in mind the difference between *Declaration* and *Instantiation* in IMyInterfaces blah = new MyConcreteClass() the left hand side is declaration, the right is instantiation. You are instantiating an instance of MyConcreteClass, not of the interface. – David Hall Jan 28 '10 at 03:42
  • It's clear but missing one very important fundamental concept that I'm obviously NOT getting. Most likely it is polymorphism in that if you have a variable of type IMyInterface someVar then that basically can be (can be switched out) for any type that implements IMyInterface because that concrete type is a IMyInterface? – PositiveGuy Jan 28 '10 at 03:52
  • To expand on David's comment, if ThisMethodShowsHowItWorks *didn't* take an interface "variable" (parameter really), then ThisMethodShowsHowItWorks would need to have overloads for MyNiftyClass, MyOddClass... and every other future class that it wanted to deal with! By declaring the parameter as IMyInterface, the author of TMSHIW doesn't have to know about all the concrete classes or predict new ones. – itowlson Jan 28 '10 at 03:52
  • @coffeeaddict - I think I get you question now. Are you asking why would your left hand declaration be of type IMyInterface ? In most cases, the answer is, it doesn't have to be if it is a locally scoped variable in a method. I usually declare it of the type of the interface I'm using for clarity. The one place where a locally scoped variable would have to be declare as the interface, is when you are using a factorymethod returning an instance. – David Hall Jan 28 '10 at 03:54
  • 5
    coffeeaddict: "polymorphism ... if you have a variable of type IMyInterface someVar then that basically ... can be switched out for any type that implements IMyInterface because that concrete type is a IMyInterface?" Exactly. `IMyInterface nifty = new MyNiftyClass()` is artificial: you wouldn't usually bother writing it. But consider, say, `IMyInterface imi = oddness > 0 ? new OddClass() : new NiftyClass()`. We don't know at compile time whether we're going to get an Odd or Nifty object, and we *don't care*: all we care is that we can pass it to TMSHIW, i.e. it's an IMyInterface. – itowlson Jan 28 '10 at 03:56
  • @itowlson - oooh, lovely example of a technical reason for a locally scoped interface declaration! – David Hall Jan 28 '10 at 04:04
  • awesome, I understand it all completely now! You have completed me (no I'm not gay) – PositiveGuy Jan 28 '10 at 05:16
  • this answer should be used in books! it perfectly explains the purpose of using an interface type variable! great +1 –  Oct 08 '13 at 08:52
  • @WeDoTDD.com you'll see how valuable programming to interfaces is when unit testing or doing test driven development. You'll also see when doing dependency injection. These areas are where the lightbulb really turns on!! – Kirby Oct 12 '16 at 01:05
  • Good answer Dave – mend0k Oct 27 '21 at 16:38
10

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.

ChaosPandion
  • 77,506
  • 18
  • 119
  • 157
  • 1
    Ok, so you're passing in the Interface Type. Why? I still don't get why. – PositiveGuy Jan 28 '10 at 03:31
  • I think you people are missing a fundamental that I don't understand. You're assuming I know all fundamentals here of Polymorphism. – PositiveGuy Jan 28 '10 at 03:53
  • dude and you're not really helping by giving me a cocky response of "it's elegant" – PositiveGuy Jan 28 '10 at 03:54
  • 1
    coffeeaddict: It may help to think about future classes. If you wrote the ReadItemsList and ReadItemsArray versions, that might work for you today. But then suppose I invented the MySuperCollection class, which is neither a List nor an array -- but does implement IEnumerable. In the first scenario, I can't use your Read methods, because you had no way of anticipating MySuperCollection. In the interface version, I can plug a MySuperCollection into ReadItems and it just works -- you don't need to change ReadItems or add a new overload or anything. – itowlson Jan 28 '10 at 04:00
  • 1
    @coffeeaddict what @Chaos is trying to say is that because List and string[] (a string array) both implement the interface IEnumarable you, or any other code, do not need to understand every concrete implementation, but instead can rely on the 1 interface IEnumable because we separate the contract of the interface away from the concrete implementation – Robert Paulson Jan 28 '10 at 04:42
  • @coffeaddict - Personally, I don't see what is cocky about my response but I apologize if it sounds that way. – ChaosPandion Jan 28 '10 at 04:51
2

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.

NotMe
  • 87,343
  • 27
  • 171
  • 245
1

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.

Shane
  • 1,255
  • 14
  • 14
1

I was in same position and took me few days to figure out why do we have to use interface variable.

 IDepartments rep = new DepartmentsImpl();

why not

 DepartmentsImpl rep = new DepartmentsImpl();

Imagine If a class implements two interfaces that contain a member with the same signature, then implementing that member on the class will cause both interfaces to use that member as their implementation.

class Test 
{
static void Main()
{
    SampleClass sc = new SampleClass();
    IControl ctrl = (IControl)sc;
    ISurface srfc = (ISurface)sc;

    // The following lines all call the same method.
    sc.Paint();
    ctrl.Paint();
    srfc.Paint();
}

}

interface IControl
{
  void Paint();
}
 interface ISurface
{
  void Paint();
}
 class SampleClass : IControl, ISurface
 {
   // Both ISurface.Paint and IControl.Paint call this method. 
 public void Paint()
 {
    Console.WriteLine("Paint method in SampleClass");
 }

}

 // Output:
 // Paint method in SampleClass
// Paint method in SampleClass
// Paint method in SampleClass

If the two interface members do not perform the same function, however, this can lead to an incorrect implementation of one or both of the interfaces.

public class SampleClass : IControl, ISurface
{
    void IControl.Paint()
    {
        System.Console.WriteLine("IControl.Paint");
    }
    void ISurface.Paint()
    {
        System.Console.WriteLine("ISurface.Paint");
    }
}

The class member IControl.Paint is only available through the IControl interface, and ISurface.Paint is only available through ISurface. Both method implementations are separate, and neither is available directly on the class. For example:

   IControl c = new SampleClass();
   ISurface s = new SampleClass();
   s.Paint();

Please do correct me if i am wrong as i am still learning this Interface concept.

user1263981
  • 2,953
  • 8
  • 57
  • 98
0

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.

Amirshk
  • 8,170
  • 2
  • 35
  • 64
  • yea read that already and MSDN usually does a crap job of explaining more advanced topics, didn't do me a damn bit of good to explain why you use ISampleInterface obj = new ImplementationClass(); Why ISampleInterface variable to create a new instace of that class? Why use the Interface as a variable instead of ImplementationClass obj = new ImplementationClass(). The ImplementationClass has already satisfied the contract so why do I need to use an ISampleInterface type of variable??? – PositiveGuy Jan 28 '10 at 03:34
  • yea, your update. So it's the same thing as if you had an Abstract class and any subclasses are of type SomeAbstractClass so you can essentially switch out for example a method param with param of type SomeAbstractClass and basically send to that method any subclass which has inherited SomeAbstractClass...right? – PositiveGuy Jan 28 '10 at 03:49
  • you might also wanna read this: http://www.codeproject.com/KB/cs/abstractsvsinterfaces.aspx – Amirshk Jan 28 '10 at 03:56
  • 1
    Good God THIS is what I was after. Everyone in the ROOM here assumes I fully understand Polymorphism and I do pretty much (Abstract classes) but I didn't really get that the same effect happens here with Interface members when you define an variable, param, or return type as type IMyInterface in your subclasses! How can nobody here understand that this is why my brain did not understand what was going on and the INTENT to use Interface based variables, parames, etc. in your subclasses. Sure I see th code, that's all fine and dandy. I just needed the non-technical explanation is all!! thx – PositiveGuy Jan 28 '10 at 04:00
0

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.

Aaron
  • 6,988
  • 4
  • 31
  • 48
0

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.

Robert Paulson
  • 17,603
  • 5
  • 34
  • 53
Ravisha
  • 3,261
  • 9
  • 39
  • 66
0

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

PostMan
  • 6,899
  • 1
  • 43
  • 51
  • 1
    Thanks but I get all that. What I don't get is creating Interface variables inside the subclasses who implement that particular interface. – PositiveGuy Jan 28 '10 at 03:30
  • I do not think that you are answering the Question: Why would you declare a variable to be of an interface type? – Guilder Dec 08 '22 at 22:12
0

No, it is not possible. Designers did not provide a way. Of course, it is of common sense also. Because interface contains only abstract methods and as abstract methods do not have a body (of implementation code), we cannot create an object..

Suppose even if it is permitted, what is the use. Calling the abstract method with object does not yield any purpose as no output. No functionality to abstract methods. Then, what is the use of interfaces in Java design and coding. They can be used as prototypes from which you can develop new classes easily. They work like templates for other classes that implement interface just like a blue print to construct a building.

Yogesh Yadav
  • 107
  • 1
  • 2
  • 6
0

I believe everyone is answering the polymorphic reason for using an interface and David Hall touches on partially why you would reference it as an interface instead of the actual object name. Of course, being limited to the interface members etc is helpful but the another answer is dependency injection / instantiation.

When you engineer your application it is typically cleaner, easier to manage, and more flexible if you do so utilizing dependency injection. It feels backwards at first if you've never done it but when you start backtracking you'll wish you had.

Dependency injection normally works by allowing a class to instantiate and control the dependencies and you just rely on the interface of the object you need.

Example:

Layer the application first. Tier 1 logic, tier 2 interface, tier 3 dependency injection. (Everyone has their own way, this is just for show).

In the logic layer you reference the interfaces and dependency layer and then finally you create logic based on only the interfaces of foreign objects.

Here we go:

public IEmployee GetEmployee(string id)
{
    IEmployee emp = di.GetInstance<List<IEmployee>>().Where(e => e.Id == id).FirstOrDefault();

    emp?.LastAccessTimeStamp = DateTime.Now;

    return emp;
}

Notice above how we use di.GetInstance to get an object from our dependency. Our code in that tier will never know or care about the Employee object. In fact if it changes in other code it will never affect us here. If the interface of IEmployee changes then we may need to make code changes.

The point is, IEmployee emp = never really knows what the actual object is but does know the interface and how to work with it. With that in mind, this is when you want to use an interface as opposed to an object becase we never know or have access to the object.

This is summarized.. Hopefully it helps.

Michael Puckett II
  • 6,586
  • 5
  • 26
  • 46
-1

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).

Jay
  • 56,361
  • 10
  • 99
  • 123
  • Interfaces are a form of programming-by-contract. From a certain viewpoint, one can argue that interfaces can be used to achieve a form of polymorphism in C#, but they are not polymorphism. Interface based programming is not limited to OO languages, and conversely OO languages do not require interfaces to function. – Robert Paulson Jan 28 '10 at 03:16
  • Yea, I get polymorphism, many types of the main type...ok that's easy to understand with abastract classes. But for me, the interface I view is some hallow "thing" and I don't see how it can have any state at all. – PositiveGuy Jan 28 '10 at 03:42
  • (Class A any implementation of IMyInterface.) Ok , but what does that me to me, break it down for me in lamens terms. Act like I don't know wtf I'm doing with Interfaces outside the fact that I know that they are a contract, and that subclasses must implement whatever members that the Interface defines. That part is easy. – PositiveGuy Jan 28 '10 at 03:44
  • There's something missing on the net, in books, ect. that is clearly something that is inferred here that I don't know yet. And so that's what I'm trying to understand. So...if you use IMyInterface someVar then someVar represents EVERY subclass that has implemented IMyInterface? And so if IMyInterface had method myInterfaceMethod then that means that my someVar can call myInterfaceMethod and it will pick some subclass out there who has implemented the myInterfaceMethod method? If that's the case then someVar is basically a multiple pointer to many subclasses! right? – PositiveGuy Jan 28 '10 at 03:47
  • CoffeeAddict, you're right, the interface itself never has any data/state/anything. The interface is just a "clue" or a "contract," depending on how you look at it, and whether you are using a strongly or weakly typed language) to the class that uses it that the object that actually gets instantiated or passed in as an argument is going to have *these properties* and *these methods*. That can be *any* class with those properties and methods (as long as they declare the interface implementation), even if that class has 40 other properties and 40 other methods (which it shouldn't). ...continued – Jay Jan 28 '10 at 03:58
  • ... this extends the polymorphic effect, because with interfaces you can have a form of multiple inheritance (which is admittedly a misleading term). When you use an interface, the variety of classes that can be used do not have to belong to the same inheritance hierarchy, which is inherently linear. For example, `int` and `string` both implement `IComparable`. You can create a method that compares two `IComparables`. You never create an IComparable, but one place you pass `int`egers to that function and in another place you pass `string`s. ...continued – Jay Jan 28 '10 at 04:03
  • ... still, the function works, because both types implement that interface, *even though `string` does not derive from `int` and `int` does not derive from `string`*. What's more, you can create your own types, implement IComparable, and pass *those* to the same function, and it will work, again without having to be part of any inheritence tree. – Jay Jan 28 '10 at 04:05
  • Robert, I must disagree with you. Google "interface-based polymorphism." You will find that Microsoft explicitly describes .NET as utilizing both inheritance-based and interface-based polymorphism. Likewise in Java. – Jay Jan 28 '10 at 04:07
  • No, CoffeeAddict, the framework doesn't pick a class. If you new() up a class like `IMyInterface someVar = new MyClass();`, where `MyClass` implements `IMyInterface`, `someVar` is simply an instance of `MyClass`, but it only "knows" that it is some form or `IMyInterface`, so in intellisense you'll only see the public members of the interface. See my explanation in a previous comment about a method that accepts a parameter, though, or consider a class that takes a constructor argument, and you'll see where this starts to get powerful. – Jay Jan 28 '10 at 04:13
  • More to the point of your question, if you simply instantiate an object by calling new(), you gain little by declaring it as `IMyInterface`. However, when striving to decrease coupling among classes, you'll try to limit any use of `new()` inside your classes. When you get into dependency injection, inversion of control containers, unit testing with mocks and stubs, and the factory pattern, you'll need to use interfaces because you'll call `IMyInterface someVar = myFactory.Build();` without knowing at design time what implementation comes back. – Jay Jan 28 '10 at 04:21
  • Bizarre. My apologies for the apparent shift in terminology. Polymorphism used to mean multiple inheritance. I must be getting old - whatever. For above comment replace polymorphism => multiple inheritance – Robert Paulson Jan 28 '10 at 04:34