Difference between an abstract class and Interface? And when to use Interface or Abstract Class in the code

Photo by Mapbox on Unsplash

Difference between an abstract class and Interface? And when to use Interface or Abstract Class in the code

One of the most asked question in an interview

Generally, students and working professional gets confused about when should one use an interface and in what situation one should use an abstract class. The one thing both interface and abstract class are used for is Abstraction. Abstraction is a process of hiding the implementation details and showing only functionality to the user. To understand their application first, let us understand these terms individually and what they mean.

What is an Interface?

In a programming language, an interface is a collection of methods, properties, and members (e.g variables). It is used to provide a way for components to communicate with each other in a standardized manner, without the need to know the implementation details of the other component. An interface defines a set of rules or guidelines that must be followed by any component that implements it. An example of the interface can be given below.

 public interface Employee {
        int ID { get; set; } //Id property
        int FirstName { get; set; } //First Name property
        int LastName { get; set; } // Last Name property
        long Salary { get; set; } // Salary property
        long CalculateSalary(Hashtable hashtable); // Calculate Salary for employee
  }

In the above example, I have declared an Employee interface that provides the list of properties and methods that need to be implemented whenever the class implements it. Whenever the class Implements the interface then it agrees to provide a specific set of functionality that can be used by other components that depend on the interface. Interfaces are often used in software design to enable modularity, flexibility, and code reuse. Let's take an example where you declare two different types of Employee i.e Full-Time Employee and Part-Time Employee. Now when you implement the interface and implement the properties and method you can see the code as given below.

public class FullTimeEmployee : Employee
    {
        int fulltimeEmployeeId=0;
        String fulltimeEmployeeFirstName=String.Empty;
        String fulltimeEmployeeLastName = String.Empty;
        double salary = 0;
        public int ID { get => fulltimeEmployeeId; set => fulltimeEmployeeId = value; }
        public String FirstName { get => fulltimeEmployeeFirstName; set => fulltimeEmployeeFirstName = value; }
        public String LastName { get => fulltimeEmployeeLastName; set => fulltimeEmployeeLastName=value; }
        public double Salary { get => salary; set => salary=value; }

        public double CalculateSalary(Dictionary<String,Double> thingsToConsider)
        {
            Salary += thingsToConsider["Pay_Per_Rate"] * 40 * 2;
            if (thingsToConsider["No_of_leaves_left"] > 0) {
                Salary += thingsToConsider["No_of_leaves_left"] * thingsToConsider["Pay_Per_Rate"];
            }

            if (thingsToConsider["Bonus"] > 0)
            {
                Salary += thingsToConsider["Bonus"];
            }

            return Salary;
        }

        public void PrintName(string FirstName, string LastName)
        {
            Console.WriteLine("Hello "+FirstName+" "+LastName);
        }
    }


    public class PartTimeEmployee : Employee
    {
        int ParttimeEmployeeId = 0;
        String ParttimeEmployeeFirstName = String.Empty;
        String ParttimeEmployeeLastName = String.Empty;
        double salary = 0;
        public int ID { get => ParttimeEmployeeId; set => ParttimeEmployeeId = value; }
        public String FirstName { get => ParttimeEmployeeFirstName; set => ParttimeEmployeeFirstName = value; }
        public String LastName { get => ParttimeEmployeeLastName; set => ParttimeEmployeeLastName = value; }
        public double Salary { get => salary; set => salary = value; }

        public double CalculateSalary(Dictionary<String, Double> thingsToConsider)
        {
            if (thingsToConsider["No_of_hours_Worked"] > 0)
            {
                Salary += thingsToConsider["No_of_hours_Worked"] * thingsToConsider["Pay_Per_Rate"];
            }

            return Salary;
        }

        public void PrintName(string FirstName, string LastName)
        {
            Console.WriteLine("Hello " + FirstName + " " + LastName);
        }
    }

In the above example, the ID, FirstName, and LastName properties, and the method and PrintName and CalculateSalary have been implemented.

What is an abstract class & abstract method?

An abstract class is a class that serves as a base or a template for other classes to inherit from. It may contain both abstract and non-abstract methods, as well as properties, fields, and other members that are common to all its derived classes. A class can be declared as abstract by using the abstract keyword. An abstract class is a class that cannot be instantiated on its own but is instead designed to be extended by other classes that provide concrete implementations of its abstract methods**.** An abstract method is a method that does not have an implementation in the abstract class but must be implemented by any derived class that extends the abstract class. An example of an abstract class is given below

 abstract public class Shape {

        public const double pi = 3.14;
        abstract public double CalculateArea();
        abstract public double CalculateVolume();

    }

In the above example, the Shape class is declared abstract as for every shape we need to calculate the area and volume for all the shapes (eg. Cylinder, Cone, cube, etc). Hence we declare it abstract as it's important for each shape class to give a concrete implementation for the area and volume method. Given below is an example of a concrete implementation of a class that extends the shape class.

public class CircularCone : Shape
    {
        int height=0,radius=0;       
        public CircularCone(int height, int radius)
        {

            this.height= height;
            this.radius = radius;
        }
        public override double CalculateArea()
        {
            return pi * this.radius * (Math.Sqrt((this.radius*this.radius) + (this.height*this.height)))* this.height * 0.5;
        }

        public override double CalculateVolume()
        {
            return pi * (1 / 3) * this.radius * this.radius *this.height;
        }
    }

In the above example, we have made a class called CircularCone which extends the Shape class and we override the base abstract methods area() and volume().

Now to the most important question when to use interface and abstract class

Interfaces and abstract methods are both used to define a contract or set of rules that must be followed by implementing classes, but there are some key differences between the two, and knowing when to use one over the other depends on the specific requirements of the project.

When to use Interface over Abstract Class?

  • When multiple unrelated classes need to implement the same contract**:** Interface is best used when a feature containing some set of rules has to be applied to multiple unrelated classes.
interface Sound {
        void makeSound();   
    }

    public class Dog : Sound { 

        public void makeSound()
        {
            Console.WriteLine("This is a dog class so it make a sound of dog");
        }
    }


    public class Trumpet : Sound { 

        public void makeSound()
        {

            Console.WriteLine("This is a Trumpet so it makes sound of trumpet");
        }
    }
  • When you need to implement multiple inheritances in your code.

When to use Abstract classes over Interface?

  • Abstract classes should be used primarily for objects that are closely related.

  • When you have partial information on the implementation of methods that is common for all the related classes.

  • The example for abstract classes is given in the above example of the Abstract class section.

Conclusion

It is very difficult to completely differentiate both the abstract class and interface as both of them provide us with the same functionality which is Abstraction. In this whole scenario abstract class and interface can be used interchangeably provided it satisfies your project requirement. The only difference between the two is the way it is implemented in the code. In the above draft I have explained the general standard that is followed to determine when to use abstract class and interface. I hope you find it useful. Happy Coding !!