Interfaces in C#

In our previous articles we have covered Classes, Inheritance, Virtual Keyword, etc. let us discuss another interesting topic, interfaces in c#.

What is an Interface?

Interfaces in C#
Interface Example in C#

The interface helps us to define a contract or group related functionality together. It is more like an abstract type where we cannot create instances. But the classes inheriting interfaces has to provide the implementation for the methods. It helps developers to write architecturally good code by leveraging various design principles.

C# supports multiple inheritances of interfaces. Since C# does not support multiple inheritances of class, with interfaces it is possible to achieve the benefit of multiple inheritances of class. Interfaces help developers to write a clean and modular code.  

An interface can contain methods, properties, events, etc. Interface members cannot have access modifiers, they are public by default.   A class (not abstract) that inherits the interfaces should provide implementation to all the members. If a class inherits two interfaces, then it should provide the implementation for all the members from both the interfaces.    Unlike classes, we cannot create the objects of the interface, but we can use interface as reference variables to point to the object of classes inherited from this interface.

Interfaces in C# with Example

The interface name begins with “I” by convention.   The below example (example are illustration purposes only not to be used in production code)gives a basic idea of the interface. An interface used to define the methods used to implement basic employee properties and methods.

using System;
namespace Learn
{
    public interface IEmployee
    {
        string Name { get; }
        double Salary { get; }
        double Bonus();
    }
    public class Employee : IEmployee
    {
        private string _firName;
        private string _lastName;
        private double _salary;

        public Employee(string firstName, string lastName, double salary)
        {
            this._firName = firstName;
            this._lastName = lastName;
            this._salary = salary;
        }

        public string Name => _firName +" "+ _lastName;
        public double Salary => _salary;
        public double Bonus()=>.1*_salary;
        public override string ToString()
        {
            return $"Name={Name},Salary={Salary},Bonus={Bonus()}";
        }
    }
    class Learn
    {
        public static void Main(string[] args)
        {
            IEmployee emp = new Employee("Adam", "John", 10000);
            Console.WriteLine(emp);
            
        }
    }
}

Let us modify the above example so that we can have two Employee type Permanent and Contract and we can add features specific to a particular employee type easily.

Employee class has a basic implementation of its properties Name and Salary. Assume that only Permanent employees are entitled to get Bonus and Contract employees are entitled to get Medical Allowance. To implement this scenario we can create 3 interfaces.

IEmployee will have basic employee properties, IPermanenttEmployee will have Bonus method & IContractEmployee will have a Medical Allowance method.Employee class is the concrete implementation of IEmployee interface.

PermanentEmployee and ContractEmployee are the concrete implementation of two types of employees. These classes implement the respective interface along with the Employee class.

using System;
namespace Learn
{

    public interface IEmployee
    {
        string Name { get; }
        double Salary { get; }
    }
    public interface IPermanentEmployee
    {
        double Bonus();

    }
    public interface IContractEmployee
    {
        double MedicalAllowance();
    }
    public class Employee : IEmployee
    {
        private string _firName;
        private string _lastName;
        private double _salary;

        public Employee(string firstName, string lastName, double salary)
        {
            this._firName = firstName;
            this._lastName = lastName;
            this._salary = salary;
        }

        public string Name => _firName + " " + _lastName;
        public double Salary => _salary;
        public override string ToString()
        {
            return $"Name={Name},Salary={Salary}";
        }
    }

    public class PermanentEmployee : Employee, IPermanentEmployee
    {
        public PermanentEmployee(string firstName, string lastName, double salary) : base(firstName, lastName, salary)
        {

        }

        public double Bonus()
        {
            return 0.1 * Salary;
        }

        public override string ToString()
        {
            return $"{base.ToString()},Bonus={Bonus()}";
        }

    }

    public class ContractEmployee : Employee, IContractEmployee
    {
        public ContractEmployee(string firstName, string lastName, double salary) : base(firstName, lastName, salary)
        {

        }
        public double MedicalAllowance()
        {
            return .05 * Salary;
        }

        public override string ToString()
        {
            return $"{base.ToString()},MedicalAllowance={MedicalAllowance()}";
        }
    }
    class Learn
    {
        public static void Main(string[] args)
        {
            IEmployee emp1 = new PermanentEmployee("Adam", "John", 2000);
            IEmployee emp2 = new ContractEmployee("Tom", "Joseph", 300);

            Console.WriteLine(emp1 as PermanentEmployee);
            Console.WriteLine(emp2 as ContractEmployee);

        }
    }
}

Explicit Interface Implementation in C#

When we have two interfaces members with the same name & a class implements both the interface. Then irrespective of the reference variable, the same method implemented in the class will be called. If we want to have different implementation then we can utilize explicit interface implementation techniques. Below example the details about explicit interface implementation.

using System;
namespace Learn
{
    //two interface has member method with same name 
    public interface IInterface1
    {
        void Print(string message);
    }
    public interface IInterface2
    {
        void Print(string message);
    }
    //class implements two interfaces 
    public class Print : IInterface1, IInterface2
    {
        void IInterface1.Print(string message)
        {
            Console.WriteLine("IInterface1:" + message);
        }
        void IInterface2.Print(string message)
        {
            Console.WriteLine("IInterface2:" + message);
        }
    }
    class Learn
    {
        public static void Main(string[] args)
        {
            Print p = new Print();
            IInterface1 i1 = p;
            IInterface2 i2 = p;
            i1.Print("Hello"); //Prints ,"IInterface1:Hello" 

            i2.Print("Hello");//Prints."IInterface2:Hello" 

        }
    }
}

Interfaces can also be Generic in C# , Check here for more information on Generic Interfaces in C# with Example.

Leave a Reply