Liskov Substitution Principle is introduced by Barbara Liskov. It is basically about the parent-child relationship (Inheritance) in Object-Oriented Design. the LSP states that if "When class S is a substitute of class T then an object of type T can be replaced by an object of type S without affecting the functionality of the existing implementation"
Points to remember,
- Types can be replaced by their subtypes without altering the desirable properties of the program.
- It has often been related to a duck test, it says "If it is lookalike a duck, quacks like a duck, but needs batteries - you probably have the wrong abstraction"
- Derived classes should be able to extend their base classes without altering the original implementation.
Example from previous posts,
public interface IEmployee
{
void CalculateSalary(Employee employee);
}
public class PermenentEmployee: IEmployee
{
public void CalculateSalary(Employee employee)
{
//Salary calculation and print the same
}
}
public class ContractEmployee: IEmployee
{
public void CalculateSalary(Employee employee)
{
//Salary calculation and print the same
}
}
public class TemporaryEmployee: IEmployee
{
public void CalculateSalary(Employee employee)
{
//Salary calculation and print the same
}
}
public class InternEmployee: IEmployee //InternType with Error
{
public void CalculateSalary(Employee employee)
{
throw new NotImplementedException(); //Violation of LSP
}
}
So here is a good example of the Open Closed Principle, but if we are talking about the Liskov then we are breaking our goal here. For example what if a new requirement suggests a new Employee type without the CalculateSalary method. Say we have an Intern type to be added in. Class InternEmployee needs to throw an exception as it does not have to do anything with that method.
Modified example with Liskov Substitution Principle,
public abstract class Employee //Abstract class
{
public virtual void CalculateSalary(Employee employee)
{
}
}
public class PermenentEmployee: Employee
{
public void CalculateSalary(Employee employee)
{
//Salary calculation and print the same
}
}
public class ContractEmployee: Employee
{
public void CalculateSalary(Employee employee)
{
//Salary calculation and print the same
}
}
public class TemporaryEmployee: Employee
{
public void CalculateSalary(Employee employee)
{
//Salary calculation and print the same
}
}
public class InternEmployee: Employee
{
//public void CalculateSalary(Employee employee) //Not required to implement the same.
}
This is the example can have much more use of object oriented programming and I am stretching the same with other design patterns going forward in further posts. I will be explaining the alternative for Virtual method in base class.
Happy learning!