Liskov Substitution Principle Demo
- [[Object Oriented Programming]] languages can't directly map the relationships between objects in the real world into the same model of relationships between them in code.
- [[Child class]]es implement IS-A relationship with base classes - naive statement of [[Object Oriented Programming]].
The problemΒΆ
- Implement rectangle and square.
- Obviously Square implements Rectangle.
namespace SOLID.LSP.Violation
{
public class Rectangle
{
public int Width { get; set; }
public int Height { get; set; }
}
public class Square : Rectangle
{
}
public class AreaCalculator
{
public static int CalcSquare(Square square) => square.Height * square.Height;
public static int CalcRectangle(Rectangle square) => square.Height * square.Width;
}
class EntryPoint
{
static void SuperMain(string[] args)
{
Rectangle rect = new Rectangle() { Width = 2, Height = 5 };
int rectArea = AreaCalculator.CalcRectangle(rect);
Console.WriteLine($"Rectangle Area = {rectArea}");
Rectangle square = new Square { Height = 2, Width = 10 };
int squareArea = AreaCalculator.CalcRectangle(square);
Console.WriteLine($"Square Area = {squareArea}");
}
}
}
The problem is that we can specify different height and with for a square, therefore the you would need to implement additional business logic for that and that solution is a violation of Liskov Substitution Principle since the Rectangle is not substitutable by square.
public static int CalcArea(Rectangle rect)
{
if (rect is Square)
{
return rect.Height * rect.Height;
}
return rect.Height * rect.Width;
}
This will be refactored in like so:
namespace SOLID.LSP.Fixed
{
public interface IShape
{
int CalculateArea();
}
public class Rectangle : IShape
{
public int Width { get; set; }
public int Height { get; set; }
public int CalculateArea() => Width * Height;
}
public class Square : IShape
{
public int SideLength { get; set; }
public int CalculateArea() => SideLength * SideLength;
}
class EntryPoint
{
static void SuperMain(string[] args)
{
IShape rect = new Rectangle { Height = 2, Width = 5 };
int rectArea = rect.CalculateArea();
Console.WriteLine($"Rectangle Area = {rectArea}");
///
IShape square = new Square() { SideLength = 10 };
int squareArea = square.CalculateArea();
Console.WriteLine($"Square Area = {squareArea}");
}
}
}