DEV Community

nineismine
nineismine

Posted on

Demystifying the C# Interface

Interfaces in programming are a subject that I have sometimes grappled with in C#. When should I use them? Why would I want to spend time writing this extra code that doesn't seem to do anything? How many methods does it take to make a good interface(and justify their existence)?

I've spent a good bit of time puzzling over thee questions. (and even outright avoiding interfaces)

I finally have a grasp on them and hopefully over the course of this post, I can explain them in a way that will demystify the concept for you.

If these are the types of questions that you have struggled with or you are just new to the concept then read on! I got you covered.

 

How do interfaces work in C# and what is this contract nonsense?

Interfaces in C# are often described as:

An interface is a contract that guarantees to a client how a class or struct will behave. When a class implements an interface, it tells any potential client “I guarantee I’ll support the methods, properties, events, and indexers of the named interface.”

An interface offers an alternative to an abstract class for creating contracts among classes and their clients. These contracts are made manifest using the interface keyword, which declares a reference type that encapsulates the contract."

Pardon me while I put on my "What the heck does that mean face". So while this is technically correct I had a really hard time puzzling those words into actionable code or a solid understanding of when to use them.

 

Interfaces started making more sense to me when I started thinking of them as behaviors.

As a beginner I tried to reconcile interfaces into a similar bucket as classes , abstract classes and other constructs. Interfaces aren't really like them at all though!

While classes define how a construct behaves , interfaces simply just ensure that we know that the construct will have a behavior .

OK, so what does that mean?

The two main questions that I needed to understand about interfaces we're not well defines in any of the material I viewed when reading about them.

  • When do I use an interface?
    • When I have a group of objects that I want to be able to collect and ultimately use based on the Interface defined behavior(s)
  • How many methods do I need to apply to an interface to justify the work of building one?
    • Just 1! (if you have the need to loop over disparate types based on their behavior)


Often when I have seen interfaces explained in other mediums they use examples where similar things have behaviors that are similar and then they try to explain to us that the interface just means each of these similar things.

In Head First Design Patterns (which I think is a great book) they explain interfaces in the context of animals, and the need for those animals to make sounds.

This example was really difficult for me to wrap my head around because why would I do this? Where would I use this?

It took a long time of my playing around with interfaces to really put together a good example of when and why I would use them.

Finding this understanding also helped me answer the question I had about "How many methods justify the use of an interface?". (hint the answer is 1!)

Here is an example that explains a situation that helped the idea click for me.

Instead of thinking about cats and dogs lets thing about all the different things that we can power on in our house.

In the above example we can see that each of the different types of devices turn on in a very different way.

Let's look at some code

Now what if we wanted to write code to play a prank and turn on everything in the house at once?

Let's assume that we have a program which has a list of all of the devices in the house. Oh wait! How do we even add a Computer , a Car and a Motion Activated Light to a collection? Don't we need to cast a List by type?

So I guess we can make three lists (and one more for every type of other device)

List<Computer> computers = new List<Computers>();

computers.Add(cpu1);

computers.Add(cpu2);

List<Car> cars = new List<Car>();

cars.Add(car1);

cars.Add(car2);

List<MotionActivatedLight>  mals = new List<MotionActivatedLight>();

mals.Add(mal1);

mals.Add(mal2);

Then we could do something like this :

Program Main()

{

foreach (Computer computer in Computers )

{

computer.TurnOn();

}

foreach (Car car in Cars)

{

car.TurnOn()

}

foreach (MotionActivatedLight mal in mals)


//turn them on

}
}

 

The thing to note here is that we need to treat each object as their own type, put them in collections by type and then iterate through each one to turn everything on.

This is where interfaces can be used to make your job sooooooooo much less tedious.

See with an interface what we are doing is guaranteeing that an object will know how to do some behavior. The objects don't really need to be related by anything other than the interface (or the shared behavior) ...

So how does this make our programming task easier???

Instead of making a list object for each type (Computer , car, Light, TV , Hair dryer, Washing Machine etc) we can make one collection and cast it as the Interface type

 

Then we can add every device in the house to this one collection! Let look at what the code above would look like using this knowledge.

List<IPowerable> powerableDevice = new List<IPowerable>();

powerableDevice.Add(cpu1);

powerableDevice.Add(car);

powerableDevice.Add(Light);

powerableDevice.Add(TV );

powerableDevice.Add(Hair dryer,);

powerableDevice.Add(Washing Machine );

As you can see we have already simplified things now because we have ONE list but now lets look at the code to turn it on.

Program Main()

{

foreach (IPowerable powerable in powerableDevice )

{

powerable .TurnOn();

}

}

See how much easier that is? This is where the "contract" that people mention comes in . See we know that IPowerable anything will always have a TurnOn() method and even though the means to do it might be totally different for each type we know that the device will know how to manage it. That is what the interface gives us.

 

 

 

 

Top comments (2)

Collapse
 
saberhosneydev profile image
Saber Hosney

That helped me a lot, I was confused with interfaces concept , thanks !

Collapse
 
nineismine profile image
nineismine

So happy to hear this. I spent so much time trying to understand why I would use them and when. Really glad this helped someone else!