这是否解决了Liskov Substitution方形矩形违规问题?

Iva*_*nov 3 oop liskov-substitution-principle solid-principles

我对SOLID设计原则很陌生.我理解的一个问题是Liskov Substition Principle违规的"方形矩形"示例.为什么Square的高度/宽度设置器会覆盖矩形的高度?当存在多态性时,这不正是导致问题的原因吗?

不删除这个解决问题?

class Rectangle
{
    public /*virtual*/ double Height { get; set; }
    public /*virtual*/ double Width { get; set; }
    public double Area() { return Height * Width; }
}

class Square : Rectangle
{
    double _width; 
    double _height;
    public /*override*/ double Height
    {
        get
        {
            return _height;
        }
        set
        {
            _height = _width = value;
        }
    }
    public /*override*/ double Width
    {
        get
        {
            return _width;
        }
        set
        {
            _width = _height = value;
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        Rectangle r = new Square();
        r.Height = 5;
        r.Width = 6;

        Console.WriteLine(r.Area());
        Console.ReadLine();
    }
}
Run Code Online (Sandbox Code Playgroud)

按预期输出为30.

ano*_*ave 10

想象一下,用户正在GUI应用程序中实现边界框,类似于:

在此输入图像描述

他们想要通过Rectangle类来表示这个蓝色框,这样如果用户点击并拖动它的高度就会增加; 如果用户向右拖动,其宽度将增加.

LSP声明客户端应该能够使用派生类(Square),无论你在哪里使用它的超类(Rectangle)而不破坏Rectangle的业务逻辑 - 即用户应该能够在一个中为另一个和其余的他们的代码不应该破坏.

但以下内容彼此不兼容:

  • 这是一个假定的Rectangle 后置条件,它的setter方法不会引起副作用(即setWidth不应影响高度)
  • Square的逻辑固有的宽度总是等于它的高度.

如果程序员使用Square而不是Rectangle,他们上面的假设就不会起作用,就像用户拖下来一样,盒子会同时水平和垂直变大.


Square/Rectangle示例的问题在于我们开始假设过多的Rectangle.矩形可以具有与其高度不同的长度,但这是特定类型的矩形(椭圆形矩形)的属性.

正方形矩形,但正方形不是椭圆形矩形.如果我们想假设关于我们Rectangle类的椭圆形行为(它的宽度和高度可以不同),那么我们的Square类从那里扩展是没有意义的.