In most of the interviews, we face the struggle to explain the scenarios for the concrete, abstract & interface classes. This leads to the interviewer to have bad impression.
Why we are moving to the abstract instead of Concrete class?
When should we use concrete, abstract, interface?
After these types of questions, we will get bit confused to answer. So in this post, we are going to discuss ‘how’ and ‘where’ to use the concrete and abstract classes.
Requirement:
Let us consider that a company requires the details like full name, salary details etc., of their employees working full time and part time. Based on the above requirement, let us create the two classes like FullTimeEmployee, PartTimeEmployee as shown below.
FullTimeEmployee Class
class FullTimeEmployee : AbstractBaseClass
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int YearlySalaray { get; set; }
public string GetFullName()
{
return this.FirstName + " " + this.LastName;
}
public override int GetMonthlySalary()
{
return this.YearlySalaray / 12;
}
}
PartTimeEmployee Class
class PartTimeEmployee : AbstractBaseClass
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int HourlySalaray { get; set; }
public int TotalHour;
public string GetFullName()
{
return this.FirstName + " " + this.LastName;
}
public override int GetMonthlySalary()
{
return this.TotalHour * this.HourlySalaray;
}
}
Disadvantage:
From the above two classes, we are able to get the details from both type of employees by creating instances of those.But we can observe that there are many repeated properties and methods presented in both classes like FirstName, LastName, GetFullName(), GetMonthhlySalray() . To avoid these type of redundancies, now we are going to create one more class called BaseEmployee to handle the common properties and methods.
Concrete Classes:
A Concrete class is a normal class so we can use it as a base class (optional), it cannot contain abstract methods.
Based on the above conclusion, the common properties and methods have moved the class called BaseEmployee. The GeMonthlySalary() method need to be declared as virtual because the BaseEmployee class doesn’t know how to provide the implementation for both the FullTimeEmployee & PartTimeEmployee classes because it is calculating the salary based on the employee’s type.
When to use?
Base class might be best option when all of your child classes can share the same implementations of the members on the base class.
BaseClass:
class BaseEmployee
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string GetFullName()
{
return this.FirstName + " " + this.LastName;
}
public virtual int GetMonthlySalary()
{
throw new NotImplementedException();
}
}
FullTimeEmployee Class
class FullTimeEmployee : BaseEmployee
{
public int YearlySalaray { get; set; }
public override int GetMonthlySalary()
{
return this.YearlySalaray / 12;
}
}
PartTimeEmployee Class
class PartTimeEmployee : BaseEmloyee
{
public int HourlySalaray { get; set; }
public int TotalHour;
public override int GetMonthlySalary()
{
return this.TotalHour * this.HourlySalaray;
}
}
If we create an instance of both classes, then application will run without any error and give results. Still we are having some disadvantages of using concrete Classes and those are mentioned below
Disadvantage:
1) There is nothing that stops us from creating an instance for the Baseclass.
2) If we access the non-defined method in the base class, then it will throw the error at runtime using instance. To overcome these types of issues, we are moving to the abstract class
EG: BaseEmployee baseEmp = new BaseEmployee()
baseEmp.GetMonthlySalary()
Abstract Class:
The Abstract class is a special / incomplete type of class, which cannot be initiated and it acts as a base class for other derived classes. An Abstract method must be implemented in the non-Abstract class using the override keyword. The method that is declared as abstract needs to be implemented by derived classes.
When we use the abstract class?
We can use abstract class when we want to move the common functionalities of two or more related classes in to the base class and we don’t want the base class to initiate.
Let us create the “AbstractBaseClass” instead of concrete Base class as shown below. The “GetMonthlySalary()” is declared as abstract so we no need to provide the implementation. So within the derived class, we are going to provide the implementation by overriding it.
abstract class AbstractBaseClass
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string GetFullName()
{
return this.FirstName + " " + this.LastName;
}
public abstract int GetMonthlySalary();
}
FullTimeEmployee Class
class FullTimeEmployee : AbstractBaseEmployee
{
public int YearlySalaray { get; set; }
public override int GetMonthlySalary()
{
return this.YearlySalaray / 12;
}
}
PartTimeEmployee Class
class PartTimeEmployee : AbstractBaseEmloyee
{
public int HourlySalaray { get; set; }
public int TotalHour;
public override int GetMonthlySalary()
{
return this.TotalHour * this.HourlySalaray;
}
}
Note:
- An abstract class can contain either abstract methods or non-abstract methods.
- Abstract members do not have any implementation in the abstract class, but the same has to be provided in its derived class.
- The access modifier of the abstract method should be same in both the abstract class and its derived class.
- An abstract class cannot be a sealed class.
- An abstract method can’t be private and static.