Principles

Last Updated: 5/2/2024

Liskov Substituion Principle

-Let φ(x) be a property provable about objects x of type T. Then φ(y) should also be true for objects y of type S where S is a subtype of T.

  • Subtypes must be substitutable for their base type.
  • 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.
  • LSP says that the derived class should correctly implement the base class methods

Example 1

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];
	}
}

Example 2

Problem

public class Rectangle 
{
	public virtual int Height {get; set;}
	public virtual int Width {get; set;}
	public virtual void Display() 
	{
		Console.WriteLine("display rect");
	}
}

public class Square: Rectangle
{
	private int _height;
	private int _width;
	
	public override int Height
	{
		get {
			return _height;
		}
		set {
			_height = value;
			_width = value;
		}
	}
	public override int Width
	{
		get {
			return _width;
		}
		set {
			_width = value;
			_height = value;
		}
	}
}

public class AreaCalculator
{
	public static int Calculate(Rectangle r)
	{
		return r.Width * r.Height;
	}
}

Rectangle obj1 = new Square();
obj1.Width = 3;
obj1.Height = 5;
Console.WriteLine(AreaCalculator.Calculate(obj1)); //25

Rectangle obj2 = new Square();
obj2.Height = 5;
obj2.Width = 3;
Console.WriteLine(AreaCalculator.Calculate(obj2));