67

I have seen an Interface instance being generated from a class many times. Why do we use interface this way? An interface instance is created only itself with the help of the derived class and we can access only these interface members through this instance. How does this give an advantage? I'm so confused.

interface IPrint
{
    void Print();
}

class Sample : IPrint
{
    public void Print()
    {
        Console.WriteLine("Print...");
    }

    public void Sample()
    {
        Console.WriteLine("Sample...");
    }
}

class Program
{
    static void Main(string[] args)
    {
        IPrint print = new Sample();
        print.Print();
    }
}
aerin
  • 20,607
  • 28
  • 102
  • 140
user2282567
  • 781
  • 1
  • 7
  • 14

4 Answers4

110

Interfaces define that a class MUST be able to do something. This means that you know the object being worked on will do what you want to be able to do. It allows you greater freedom and is one of the advantages of OOP. This is a deep topic but a very basic example would be this:

public interface IAnimal
{
    string Speak();
}

public class Dog : IAnimal
{
    public string Speak()
    {
        return "Woof, woof";
    }
} 

public class Cat : IAnimal
{
    public string Speak()
    {
        return "Meow";
    }
} 

public class Parrot : IAnimal
{
    public string Speak()
    {
        return "Sqwark!";
    }
} 

Then you could use any animal you like!

class Program
{
    static void Main(string[] args)
    {
        // Writes Woof, Woof
        IAnimal animal = new Dog();
        Console.WriteLine(animal.Speak());        

        // Now writes Meow
        animal = new Cat();
        Console.WriteLine(animal.Speak());

        // Now writes Sqwark etc
        animal = new Parrot();
        Console.WriteLine(animal.Speak());
    }
}

This also allows you to then get into things like Inversion Of Control where you would take an item in like this and you could pass a dog, cat or parrot and the method would always work, not knowing or caring which animal it was:

public void ShoutLoud(IAnimal animal)
{
    MessageBox.Show("Shout " + animal.Speak());
}

This then makes ShoutLoud unit testable because you could use a mock object rather than a real animal. It basically makes your code flexible and dynamic rather than rigid and tightly coupled.

Also, expanding on Matthew's question. In C# you can only inherit from one base class but you can have multiple interfaces. So, you could have:

public class Dog : IAnimal, IMammal, ICarnivor

This allows you to have small interfaces (recommended) that then allow you to build up so giving maximum control over what an item can / must do.

Andy123
  • 13
  • 5
Belogix
  • 8,129
  • 1
  • 27
  • 32
  • 2
    I ask the same question I ask KillerCam: From this example, what benefit do you get from using an interface rather than a base class with virtual methods? For example, if you change IAnimal to `public abstract class Animal { public abstract string Speak(); }` – Matthew Watson May 30 '13 at 09:38
  • 2
    @MatthewWatson - Good question and I've updated my answer (see at the bottom) for just one reason an interface is beneficial. – Belogix May 30 '13 at 09:42
  • 2
    Great answer from @Belogix particular this comment: "Inversion Of Control where you would take an item in like this and you could pass a dog, cat or parrot and the method would always work". So you could have a method called FeedAnimals which would feed all animals that belong to the interface IAnimal type – Trevor Jul 26 '16 at 15:42
  • 1
    Great answer with apt examples! – KBNanda Jun 25 '21 at 18:42
10

Using an interface this way gives you the ability to create methods that use standard template of the interface. So here you might have many classes of printer that all inherit from IPrinter

class SamsungPrinter : IPrinter
{
    // Stuff and interface members.
}

class SonyPrinter : IPrinter
{
    // Stuff and interface members.
}

interface IPrinter
{
    void Print();
}

So for each type SamsungPrinter, SonyPrinter, etc. you can pre-process using something like

public static void PreProcessAndPrint(IPrinter printer)
{
    // Do pre-processing or something.
    printer.Print();
}

You know from inheriting from IPrinter and using that type in the method parameters that you can always safely use the Print method on what ever object is passed.

Of course there are many other uses for using interfaces. One example of their use is in design patterns, in particular the Factory and Strategy patterns. The description of which and examples can be found here.

I hope this helps.

MoonKnight
  • 23,214
  • 40
  • 145
  • 277
1

But how does this differ from, for example, using a base class with virtual methods?

You are all in the assumption that one programmer or one program writes the interface and the classes, but this doesn't always have to be this way.

Maybe you have a complete finished program that works with animals and you have this worked out using:

public abstract class Animal { public abstract string Speak(); }

And then some day you download some awesome DLL from nuget that shows pictures for animals. The class library contains a contract - interface - 'IAnimal':

namespace AwesomeAnimalLibrary
{
public interface IAnimal
{
string AnimalName;
}
}

The class library also maybe contains :

namespace AwesomeAnimalLibrary
{
public class AnimalPhotos
{
[Byte] GetPhotos(IAnimal animal);
}
}

What could you do now ? Your bas class Animal can implement the AwesomeAnimalLibrary IAnimal interface and that's it.

Don't assume that other people will use you abstract base classes but work together using interface contracts.

Krijn
  • 41
  • 2
0

Interface can not have instance because interface implements only signatures of properties or methods. Interface is just a pointer to an instance of some class:

interface IExample
{
   // method signature
   void MyMethod();
}
public class MyClass : IExample
{
   // method implementation
   public void MyMethod()
   {
      ConsoleWriteline("This is my method");
   }
}

// interface pointing to instance of class
IExample ie = new MyClass();
ie.MyMethod();
cembo
  • 1,039
  • 2
  • 9
  • 18