C# Interface

Interface is like a class that contains only a definition of methods, events and properties. Interface is like a class that cannot be instantiated, interface define the abilities unlike a class that defines what an object is.
 The purpose of an interface is to define a set of requirements that a class must implement. A class can inherit from multiple interfaces, and an interface can be implemented by many classes. 

 Interface members are automatically public, no access modifiers are allowed on interface members and they can also not be static.
An interface cannot include an instance constructor because an interface cannot be instantiated.
An interface cannot inherit from a class.
An interface cannot contain fields and constants.

An interface can be declared by attaching an interface keyword before the name of the interface and that is it, by convention I is used in naming an interface.

    interface IShapeComputer
    {
        string ShapeName { get; set; }
        void ComputeVolume();
        void ComputeArea();
    }
     
The above code declare a shape interface called IShapeComputer, the I letter is used by convention when declaring an interface, you dont have to name an interface with I but it is recommended to do so. Any class that implements the IShape interface must provide the definitions for all the interface's methods and properties, failing to do so causes a compile time error.

    interface IShapeComputer
    {
        string ShapeName { get; set; }
        void ComputeVolume();
        void ComputeArea();
    }

    class Cuboid : IShapeComputer
    {
        double Bridth;
        double Length;
        double Height;
        double Volume;
        double Area;

        public Cuboid(double Bridth, double Length, double Height)
        {
            this.Bridth = Bridth;
            this.Height = Height;
            this.Length = Length;

            Volume = 0;
            Area = 0;
        }
        private string _ShapeName = "Cuboid";

        public string ShapeName { get => _ShapeName; set => _ShapeName = value; }

        public void ComputeArea()
        {

            Area = 2 * (Bridth + Length + Height);
            Console.WriteLine($"The area of the {ShapeName} is {Area}");

        }

        public void ComputeVolume()
        {

            Volume = Bridth * Length * Height;
            Console.WriteLine($"The volume of the {ShapeName} is {Volume}");
        }
    }

    class Cube : IShapeComputer
    {
        private string _ShapeName = "Cube";
        double Side;
        double Area;
        double Volume;

        public Cube(float Side) => this.Side = Side;
        public string ShapeName { get => _ShapeName; set => _ShapeName = value; }

        public void ComputeArea()
        {
            Area = 6 * Math.Pow(Side, 2);
            Console.WriteLine($"The area of the {ShapeName} is {Area}");
        }

        public void ComputeVolume()
        {
            Volume = Side * Side * Side;
            Console.WriteLine($"The volume of the {ShapeName} is {Volume}");
        }
    }

    class Sphere : IShapeComputer
    {
        double radius;
        private string _ShapeName = "Sphere";
        double Area;
        double Volume;

        public Sphere(double radius)
        {
            this.radius = radius;
        }

        public string ShapeName { get => _ShapeName; set => _ShapeName = value; }

        public void ComputeArea()
        {
            Area = 4 * Math.PI * Math.Pow(radius, 2);
            Console.WriteLine($"The area of the {ShapeName} is {Area}");
        }

        public void ComputeVolume()
        {
            Volume = (4 * Math.PI * Math.Pow(radius, 3)) / 3;
            Console.WriteLine($"The volume of the {ShapeName} is {Volume}");
        }
    }


    class InterfaceDemo
    {

        static void Main()
        {
            Console.WriteLine("\n\n............................. \n");
            var cuboid = new Cuboid(10, 18, 32);

            cuboid.ComputeArea();
            cuboid.ComputeVolume();

            Console.WriteLine("............................. \n");

            var cube = new Cube(8);

            cube.ComputeArea();
            cube.ComputeVolume();

            Console.WriteLine("............................. \n");

            var sphere = new Sphere(4);

            sphere.ComputeArea();
            sphere.ComputeVolume();

        }
    } 
     
In the above code we implemented the interface IShapeComputer in three classes Cube Cuboid and Sphere. Each shape has its own way of calculating its volume and area,note that we did not include public keyword in the declaration of the methods because interface defintions are implicitly public. Lets implement the IShapeComputer interface in a 2D shape class.

 
  
     class Circle : IShapeComputer
       {
        double radius;
        private string _ShapeName = "Circle";
        double Area;     
        public Circle(double radius)
        {
            this.radius = radius;
        }

        public string ShapeName { get => _ShapeName; set => _ShapeName = value; }

        public void ComputeArea()
        {
            Area =  Math.PI * Math.Pow(radius, 2);
            Console.WriteLine($"The area of the {ShapeName} is {Area}");
        }

        public void ComputeVolume()
        {      
            Console.WriteLine($"{ShapeName} has no  volume");
        }
    }
  
Note how we implement the interface in a 2D shape, since 2D shape has no volume, we simply print to the console. Even though there is nothing to calculate in theComputeVolume() method we must implement the method because failure to do so will result in a compile time error.
Now let us look at another example of an interface.
  
  
    interface ICalculateEmployeeSalary
    {
        int HourWorkWeek { get; set; }
        decimal PaymentPerHour { get; set; }
        decimal Salary { get; set; }   
        void ComputeSalary();
    }
  
The above code shows a definition of an interface ICalculateEmployeeSalary we can plug in any Employee to the interface and implements how the employee should be paid. Lets look at the implementations of the interface.
  
  
    interface ICalculateEmployeeSalary
    {
        int HourWorkWeek { get; set; }
        decimal PaymentPerHour { get; set; }
        decimal Salary { get; set; }   
        void ComputeSalary();
    }
    
    
    public class Accountant : ICalculateEmployeeSalary
    {
        private int hourworkweek;
        private decimal paymentperhour;
        private decimal salary;
        private string job = "Accountant";   
        public string Name { get; set; }
        public int Age { get; set; }
        public string Address { get; set; }
        public string Job => job;

        // Implemented properties
        public int HourWorkWeek { get => hourworkweek; set => hourworkweek = value; }
        public decimal PaymentPerHour { get => paymentperhour; set => paymentperhour = value; }
        public decimal Salary { get => salary; set => salary = value; }

        public Accountant(string name, int age, string address, int hourworkweek, decimal payperhour)
        {
            HourWorkWeek = hourworkweek;
            PaymentPerHour = payperhour;
            Name = name;
            Age = age;
            Address = address;
     
        }

        public void ComputeSalary()
        {        
            Salary = (HourWorkWeek * 52) * PaymentPerHour;
  
            decimal weekly_earning = Salary / 52;
            decimal monthly_earning = Salary / 12;

            Console.WriteLine("The employee salary is:");
            Console.WriteLine($"Weekly salary:{weekly_earning}");
            Console.WriteLine($"Monthly salary:{monthly_earning}");
            Console.WriteLine($"Annual salary:{Salary}");

        }

    }

    public class Technician : ICalculateEmployeeSalary
    {
        private int hourworkweek;
        private decimal paymentperhour;
        private decimal salary;
        private string job = "Machine operator"; 
        public string Job => job;
        public string Name { get; set; }
        public int Age { get; set; }
        public string Address { get; set; }
        private decimal HazardAllownce = 250;
        // implemented properties
        public int HourWorkWeek { get => hourworkweek; set => hourworkweek = value; }
        public decimal PaymentPerHour { get => paymentperhour; set => paymentperhour = value; }
        public decimal Salary { get => salary; set => salary = value; }


        public Technician(string name,int age,string address, int hourworkweek, decimal payperhour)
        {
            HourWorkWeek = hourworkweek;
            PaymentPerHour = payperhour;
            Name = name;
            Age = age;
            Address = address;
         
        }

        public void ComputeSalary()
        {  
            Salary = (HourWorkWeek * 52) * PaymentPerHour;        
            Salary += HazardAllownce;
       
            decimal weekly_earning = Salary/52;
            decimal monthly_earning = Salary/12;
 
            Console.WriteLine("The employee salary is:");
            Console.WriteLine($"Weekly salary:{weekly_earning}");
            Console.WriteLine($"Monthly salary:{monthly_earning}");
            Console.WriteLine($"Annual salary:{Salary}");

        }

    }

    class SalaryComputer
    {
        static void Main()
        {
            Technician technician = new Technician("Othman Abbas", 42, "No.19 Along central park road", 22, 35);
            Console.WriteLine("................................");
            Console.WriteLine($"{technician.Name} job {technician.Job} age {technician.Age} live {technician.Address}");
            technician.ComputeSalary();
            Console.WriteLine("\n The new employee salary is:");
            technician.PaymentPerHour = 40;
            technician.ComputeSalary();
            Console.WriteLine("................................ \n");

            var accountant = new Accountant("\n Mat Allen", 22, "Room no.5 Moonlight appartment ", 18, 30);

            Console.WriteLine("................................");
            Console.WriteLine($"{accountant.Name} job {accountant.Job} age {accountant.Age} live {accountant.Address}");
            accountant.ComputeSalary();
            Console.WriteLine("\n The new employee salary is:");
            accountant.PaymentPerHour = 35;
            accountant.ComputeSalary();
            Console.WriteLine("................................ \n");

        }
    }
  
In the above code we provide different implementation for each employee.
 
Explicit interface implementation 

 Explicit interface implementation allow us to implement two interfaces that have the same member with the same signature.If we did not implement the interface members explicitly both interfaces will use the implementation the class provide.  

    interface IAccelerateBike
    {
        void Accelerate();
    }

    interface IAccelerateCar
    {
        void Accelerate();
    }

    class VehicleAccelerator : IAccelerateBike, IAccelerateCar
    {
        float speed = 0;

        public void Accelerate()
        {
            speed += 11;
            Console.WriteLine("Accelerating......");
        }
    }

    class VehicleTest
    {
        static void Main()
        {
            VehicleAccelerator vehicleAccelerator = new VehicleAccelerator();
            vehicleAccelerator.Accelerate();
        }
    }
  
  
As you can see both interface use one implementation. If we want each interface to have its own unique implementation we implement them explicitly by using the interface name in front of the methods name. ie IAccelerateBike.Accelerate() .
 
    
        class VehicleAccelerator : IAccelerateBike, IAccelerateCar
    {
        float speed = 0;

        void IAccelerateBike.Accelerate()
        {

            speed += 11;
            Console.WriteLine("Accelerating......");
        }

        void IAccelerateCar.Accelerate()
        {
            speed += 21;
            Console.WriteLine("Accelerating......");
        }
    }
           
      
If we explicitly implement an interface that means the member is only available through the interface since it is specific to it. We caanot call the member through the impelementing class's object.
  
    interface IAccelerateBike
    {
        void Accelerate();
    }

    interface IAccelerateCar
    {
        void Accelerate();
    }

    class VehicleAccelerator : IAccelerateBike, IAccelerateCar
    {
        float speed = 0;

        public void Accelerate()
        {
            speed += 11;
            Console.WriteLine("Accelerating......");
        }
    }

    class VehicleTest
    {
        static void Main()
        {
            VehicleAccelerator vehicleAccelerator = new VehicleAccelerator();
            vehicleAccelerator.Accelerate();
        }
    }
  
  
As you can see both interface use one implementation. If we want each interface to have its own unique implementation we implement them explicitly by using the interface name in front of the methods name. ie IAccelerateBike.Accelerate() .
 
    
    class VehicleTest
    {
        static void Main()
        {
            VehicleAccelerator vehicleAccelerator = new VehicleAccelerator();


            IAccelerateBike accelerateBike = vehicleAccelerator;
            accelerateBike.Accelerate();

            IAccelerateCar accelerateCar = vehicleAccelerator;
            accelerateCar.Accelerate();

        

        }
    }
           
      
The member is not available through the class's object since we implement the two interfaces explicitly.






Interface summary


  • Interface contains a definitions of capabilities that a class or struct must implement, interface defines the ability of a class
  • Interface makes it easy to abstract a code,this is really important in programming
  • Interface can only contain methods,properties,envents and indexers
  • Interface can inherit from another interface
  • Interface makes it possible for a classe to have a multible capability from a different interfaces. This useful because multiple inheritance is not allowed in C#
  • Interface can not be instantiated

Comments

Popular posts from this blog

C# class