Principles

Last Updated: 10/8/2024

Liskov Substitution Principle

  • Subtypes (derived classes) must be substitutable for their base types (parent classes) without altering the correctness of the program
  • This means if you have a base class and a derived class, you should be able to use instances of the derived class wherever instances of the base class are expected, without breaking the application.
  • LSP guides how to use inheritance in object-oriented programming. It is about subtyping, and how to correctly derive a type from a base type.

Example 1

Problem

internal interface IVehicle
{
    void StartEngine();
}
internal class Car : IVehicle
{
    public void StartEngine()
    {
        Console.WriteLine("Starting car");
    }
}
internal class Bicycle : IVehicle
{
    public void StartEngine()
    {
        throw new NotImplementedException();
    }
}
internal class Mechanic
{
    public void CheckVehicle(IVehicle vehicle)
    {
        vehicle.StartEngine();
    }
}

Solution


internal interface IVehicle
{
	void Start();
}
internal class Car : IVehicle
{
    public void Start()
    {
        Console.WriteLine("Starting car");
    }
}
internal class Bicycle : IVehicle
{
    public void Start()
    {
        Console.WriteLine("Pedalling Cycle");
    }
}
internal class Mechanic
{
    public void CheckVehicle(IVehicle vehicle)
    {
        vehicle.Start();
    }
}
public class Program
{
	public static void Main()
	{
		var bicycle = new Bicycle();
		var mechanic = new Mechanic();
		mechanic.CheckVehicle(bicycle);
		
		var car = new Solution.Car();
		mechanic.CheckVehicle(car);
	}
}

Code

Example 2

Problem

public interface IMyCollection
{
	void Add(int item);
	void Remove(int item);
	int Get(int index);
}

public class ReadOnlyCollection: IMyCollection 
{
    private IList _collection;
	
	public ReadOnlyCollection(IList collection) {
	 	_collection = collection;
	}
	
	public void Add(int item)
	{
		throw new NotImplementedException();
	}
	public void Remove(int item)
	{
		throw new NotImplementedException();
	}
	public int Get(int index)
	{
		return (int)_collection[index];
	}
}

  • MyReadOnlyCollection class implements the IMyCollection interface but it throws NotImplementedException for two methods Add() and Remove()

Solution

public interface IMyReadOnlyCollection
{
	int Get(int index);
}

public class ReadOnlyCollection: IMyReadOnlyCollection 
{
    private IList _collection;
	
	public ReadOnlyCollection(IList collection) {
	 	_collection = collection;
	}
	
	public int Get(int index)
	{
		return (int)_collection[index];
	}
}