Introduction
An interface is not a class but is syntactically similar to an abstract base class. However, an interface has no implementation, it only has the definition of the methods without the body.
Why do we use Interfaces?
Let’s suppose we have a video streaming player software product which we have sold to many of our clients and provided support to them. Client 1 and client 2 have subscribed to our APIs for the product and implemented their own. They both have the same requirements and are happy with the current exposure of the API system. So, we have created a common base class and provided it to both of them to implement it at their end with their functionality.
- public class VideoPlayer
- {
- public virtual void Play()
- {
- Console.WriteLine("Base class Play");
- }
-
- public virtual void Pause()
- {
- Console.WriteLine("Base class Pause");
- }
- }
-
- public class Client1 : VideoPlayer
- {
- public override void Play()
- {
- Console.WriteLine("Start Video for Client 1.");
- }
-
- public override void Pause()
- {
- Console.WriteLine("Pause Video for Client 1.");
- }
- }
-
- public class Client2 : VideoPlayer
- {
- public override void Play()
- {
- Console.WriteLine("Start Video for Client 2.");
- }
-
- public override void Pause()
- {
- Console.WriteLine("Pause Video for Client 2.");
- }
- }
But, after some time, client 2 has a requirement to add some other functionality with the current functionalities in the system. He wants to add a “FastForward” action. What we should do now?
We have 2 options here.
We can add the new functionality method to the existing class and pass it to client 2 to implement it at their end.
- public class VideoPlayer
- {
-
-
- public virtual void FastForward()
- {
- Console.WriteLine("Base class FastForward");
- }
- }
-
- public class Client2 : VideoPlayer
- {
-
-
- public override void FastForward()
- {
- Console.WriteLine("fastForward Video for Client 2.");
- }
- }
But, we have a problem with this approach. Now, the new functionality will also be available for Client 1 as well because they both use the same base class and Client 1 does not want it.
We can create another class with the new functionality and pass it to client 2 to implement at their end. But, as we know C# does not support multiple inheritance, Client 2 cannot inherit the new class into the existing functionality.
- public class AddedFunc
- {
- public virtual void FastForward()
- {
- Console.WriteLine("New Base class FastForward");
- }
- }
-
- public class Client2 : VideoPlayer , AddedFunc
- {
- public override void Play()
- {
- Console.WriteLine("Start Video for Client 2.");
- }
-
- public override void Pause()
- {
- Console.WriteLine("Pause Video for Client 2.");
- }
-
- public override void FastForward()
- {
- Console.WriteLine("fastForward Video for Client 2.");
- }
- }
So, how can we solve this?
The answer is by using “Interface”.
We will write and pass to Client 2 an interface which contains the new functionality method in it. So, they can use it at their end with their functionality to use. By doing this, only Client 2 will get the new functionality and not Client 1. Since, in C#, Interfaces came into the picture to cover the multiple inheritance concept, the client does not have any problem inheriting it along with the class which contains the original functionality.
- public interface AddedFunc
- {
- void FastForward();
- }
-
- public class Client2 : VideoPlayer , AddedFunc
- {
- public override void Play()
- {
- Console.WriteLine("Start Video for Client 2.");
- }
-
- public override void Pause()
- {
- Console.WriteLine("Pause Video for Client 2.");
- }
-
- public void FastForward()
- {
- Console.WriteLine("fastForward Video for Client 2.");
- }
- }
This is scenario 1. Now, imagine a different scenario. As mentioned above, Client 1 and client 2 have the same requirements and are happy with the current implementation of the system. We provide them the classes having the business logic and expose the references to clients to implement it with their own logic. What if, in the future, they will extract the business logic from references you have provided to them? This is a threat to security.
So, another reason to use Interfaces is security.
For security reasons, we should not share the business implementation to the client side. In many places, we see Interfaces as a “Contract” of behavior. When using interface, clients have no implementation of the code. They depend on the Interface to make a call to the business code. It behaves like a mediator.
To achieve this, always write the interface name before method, like in the below code.
- public class Client2 : VideoPlayer , AddedFunc
- {
-
-
- void AddedFunc.FastForward()
- {
- Console.WriteLine("fastForward Video for Client 2.");
- }
- }
-
- By doing so, client cannot call method by its instance, like:
-
- Client2 c2 = new Client2();
- c2.FastForward();
-
- It must be like:
- AddedFunc af = new Client2();
- af.FastForward();
Properties of Interfaces
Some basic properties of interfaces are as below -
- Once an interface is defined, any number of classes can implement it. Also, one class can implement any number of interfaces. C# doesn't support multiple inheritance. To support this, interfaces came into the picture.
- Interfaces can contain methods, indexers, properties, and events. On the other side, they cannot have constants, fields, operators, types.
- Interface members are automatically public and they cannot include access modifiers.
- An interface cannot be instantiated directly. Its members are implemented by the class that implements the interface.
- Any class that implements an interface must implement all of its members.
We have some examples below.
Use of Access Modifiers will throw a compile-time error.
- public interface ITest1
- {
- void Print();
-
- }
We can create properties in Interfaces like below.
- public interface Ifirst
- {
- int a { get; set; }
- }
But, we cannot declare datatypes in it. The below code will throw a compile time error: "Interfaces cannot contain fields".
- public interface Ifirst
- {
- int x = 0;
- }
Inherit a class from multiple interfaces that may have methods with the same name or signature (Explicit Interface Implementation).
Let's write an Interface 1,
- public interface ITest1
- {
- void Print();
- }
Let's write an Interface 2,
- public interface ITest2
- {
- void Print();
- }
We have created 2 interfaces above and now we will create a class that will implement these Interfaces,
- class ImplementInterface : ITest1, ITest2
- {
- void ITest1.Print()
- {
- Console.WriteLine("First Interface Method");
- }
-
- void ITest2.Print()
- {
- Console.WriteLine("Second Interface Method");
- }
- }
Now, we make a call to these methods.
- ITest1 test1 = new ImplementInterface();
- test1.Print();
-
- ITest2 test2 = new ImplementInterface();
- test2.Print();
I hope this will be helpful.