Introduction
There is a lot of confusion between what is the purpose of an interface. According to a definition: an interface is a contract that specifies the capabilities that an implementing class should provide. The answer is to make loosely coupled applications.
Example: Suppose your car is broken with a flat tire, you don't go and change the steering wheel of a car, you only change the tire hence making tire an independent part of a car.
Let's implement an interface with a real-life situation. Every year the government presents the union budget.
As per new policies tax calculation changes. So, one has to change their application again and again with respect to new changes.
Rather than changing classes that are dependent, one can make application-independent to calculation (by creating calculator interface), hence making it loosely coupled application.
-
-
-
- interface Calculator
- {
-
-
-
-
- float CalculateTax(float interestRate);
- }
Rules:
1. No methods in an interface have a body, if you try to add body you will get a compile-time error.
2. An interface is like an abstract base class with only abstract members. Any class or struct that implements the interface must implement all its members.
3. An interface can't be instantiated directly. Its members are implemented by any class or struct that implements the interface.
4. Interfaces can contain events, indexers, methods, and properties.
5. Interfaces contain no implementation of methods (In C# 8.0, Interfaces can have a default implementation for methods).
6. A class or struct can implement multiple interfaces. A class can inherit a base class and also implement one or more interfaces.
Let's go ahead and implement our interface.
Assume it's 2019 and you need to calculate Interest Rates as per the new budget.
To serve the above purpose, we need to create the following class.
-
-
-
- class CalculateTax2019 : Calculator
- {
-
-
-
-
-
- public float CalculateTax(float interestRate)
- {
- int amount = 25000;
- return (amount * interestRate) / 100;
- }
- }
Our class CalculateTax2019 here implements Calculator interface which defines body for CalculateTax method.
In 2020 we don't have to change the implementation of our beloved class CalculateTax2019. all we have to focus is on our Calculator interface.
-
-
-
- class CalculateTax2020 : Calculator
- {
-
-
-
-
-
- public float CalculateTax(float interestRate)
- {
- int amount = 35000;
- return (amount * interestRate) / 100;
- }
- }
Note: These classes only have one method, so this is for the purpose of understanding. In real-life projects, it's become hectic work to manage tightly-coupled classes. But what makes our application loosely coupled, you ask?
- class Program
- {
- static void Main(string[] args)
- {
- Calculator InterestRates = GetRateFor2019();
- }
-
-
-
-
-
- private static Calculator GetRateFor2019()
- {
- return new CalculateTax2019();
- }
-
-
-
-
-
- private static Calculator GetRateFor2020()
- {
- return new CalculateTax2020();
- }
- }
As you see in our main method, we have GetRateFor2019 method for 2019 and can be stored in our calculator class. The same goes for method GetRateFor2020.
Now, if I made any changes in class CalculateTax2020, say I add new method ReturnGST() which will have 0 effect on my TaxCalculation implementation. Making My Tax Calculation completely independent of anything else. plus having common standards for different implementation in our case it was Tax for the year 2019 - 2020.
-
-
-
- class CalculateTax2020 : Calculator
- {
-
-
-
-
-
- public float CalculateTax(float interestRate)
- {
- int amount = 35000;
- return (amount * interestRate) / 100;
- }
-
-
-
-
-
-
-
- public float ReturnGST(int amount, float IntRate){
-
- return amount * IntRate;
- }
- }
- class Program
- {
- static void Main(string[] args)
- {
- Calculator InterestRates2019 = GetRateFor2019();
- Calculator InterestRates2020 = GetRateFor2020();
- float GST2020 = GetGST();
- }
-
-
-
-
-
- private static Calculator GetRateFor2019()
- {
- return new CalculateTax2019();
- }
-
-
-
-
-
- private static Calculator GetRateFor2020()
- {
- return new CalculateTax2020();
- }
-
-
-
-
-
- private static float GetGST()
- {
- CalculateTax2020 obj = new CalculateTax2020();
- return obj.ReturnGST(100000, 18);
- }
- }
Summary
Don't worry about the implementation, as this example was only for understanding interfaces. In real life, we don't write code in such a way. Instead, we will use a Design pattern called Dependency Injection. You can check my blog here for the same
DI Implementation.
Thank you so much for visiting this blog, I hope you were helped by this. If you have any queries, please connect with me.
Happy Coding. Have a good day :)