0

考虑 Java 中的经典示例

// Violation of Likov's Substitution Principle
class Rectangle
{
    protected int m_width;
    protected int m_height;

    public void setWidth(int width){
        m_width = width;
    }

    public void setHeight(int height){
        m_height = height;
    }


    public int getWidth(){
        return m_width;
    }

    public int getHeight(){
        return m_height;
    }

    public int getArea(){
        return m_width * m_height;
    }   
}

class Square extends Rectangle 
{
    public void setWidth(int width){
        m_width = width;
        m_height = width;
    }

    public void setHeight(int height){
        m_width = height;
        m_height = height;
    }

}

class LspTest
{
    private static Rectangle getNewRectangle()
    {
        // it can be an object returned by some factory ... 
        return new Square();
    }

    public static void main (String args[])
    {
        Rectangle r = LspTest.getNewRectangle();

        r.setWidth(5);
        r.setHeight(10);
        // user knows that r it's a rectangle. 
        // It assumes that he's able to set the 
        //   width and height as for the base class

        System.out.println(r.getArea());
        // now he's surprised to see that the area is 100 instead of 50.
    }
}

我认为重点是子类的对象可以像 Java 这样的静态类型语言中的父类一样处理(类型转换?)

Rectange rectange = new Square();

但在 Ruby 中,我认为这没有任何意义,在 Ruby 中也是如此:

class Rectangle
    attr_accessor :width, :height

    def getArea()
       @width * @height
    end
end

class Square < Rectangle

    def width=(number)
        super(number)

        @height = number
    end

    def height=(number)
        super(number)
        @width = number
    end
end

s = Square.new(100)

puts s.class

s.width = 50

puts s.height

成为我总是可以使用以下方法检查对象的类:

rectange.class

在这种情况下,如果 Ruby 中的代码将返回Square

所以我不会像对待它一样对待它Rectange

谁能解释一下在像 Ruby 这样的动态类型语言中应用 LSP 的意义?


虽然我仍然不知道让 Square 成为 Rectangle 的孩子可能会导致什么问题。 但现在我学会了通过以下方式判断LSP是否紫罗兰色:

for squareobject 是SquareClass 的一个实例,rectangleobject 是Rectangleclass的一个实例

width=是他们两个中的一种方法

width=insquare不能用width=in代替rectangle

因为它不会像 'square' 中定义的那样设置高度。

我的这种思维方式错了吗?

并且我还学会了使用紫罗兰Rectangle类中的'width='方法来分析这个问题:

width=“矩形”类中

前提:@width并且@height有一定的价值。

postconditon:@width更改为新值,@height保持不变。

对于Square类中的“宽度=”

前提:同上

postconditon: '@width' 更改为新值,@height更改为新值

原则:要求不多,承诺不少

@height改变了,所以承诺没有实现,因此它不能是继承

有没有人可以通过使用给我一些关于我分析这个问题的方式的建议DBC

4

1 回答 1

2

LSP 仍然适用,即使在像 Ruby 这样的动态类型语言中也是如此。你的推理:

我总是可以使用以下方法检查对象的类:

rectange.class

在这种情况下,如果 Ruby 中的代码会返回Square,所以我不会将其视为Rectangle.

不是特定于 Ruby 的;事实上,您也可以在 Java 中检查变量的实际类。这样做并不能为这个问题提供“解决方案”。

这个例子的关键观察是,虽然正方形是几何中的矩形,但从 OOP 的角度来看, aSquare 不是a —— a 的行为与 a的行为不兼容。RectangleSquareRectangle

于 2013-06-13T00:04:45.347 回答