Имеет ли смысл LSP для языка динамической типизации, такого как Ruby?

Рассмотрим классический пример на 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,

Может ли кто-нибудь объяснить мне смысл применения LSP в динамически типизированном языке, таком как Ruby?


Хотя я до сих пор не знаю, какую проблему может вызвать то, что Square станет дочерью Rectangle. но теперь я учусь говорить, фиолетовый ли это LSP или нет, используя способ:

за square объект является экземпляром Square Учебный класс, rectangle объект является экземпляром Rectangle учебный класс

width= это метод в обоих из них

width= в square не может быть заменено width= в rectangle

потому что он не будет устанавливать высоту, как определено в 'квадрат'.

Я не прав с таким образом мышления?

А также я научился использовать фиолетовый контакт метода 'width =' в Rectangle Класс для анализа этой проблемы:

за width= в классе "Прямоугольник"

Предпосылка: @width а также @height имеет какое-то значение.

postconditon: @width изменить на новое значение, @height остаться нетронутым

для 'width =' в Square учебный класс

предварительное условие: то же, что и выше

postconditon: "@width" меняется на новое значение, @heightизменить на новое значение

по принципу: не требуй больше, обещай не меньше

@height изменено, поэтому обещание не выполняется, поэтому оно не может быть наследством

Кто-нибудь может дать мне несколько советов о моем способе анализа этой проблемы с помощью DBC?

1 ответ

LSP по-прежнему применяется, даже в динамически типизированных языках, таких как Ruby. Ваши рассуждения:

Я всегда могу проверить класс объекта с помощью:

rectange.class

в этом случае, если код в Ruby вернется Square так что я не буду относиться к этому как Rectangle,

Не относится к Ruby; вы также можете проверить фактический класс переменной в Java. Это не дает "решения" этой проблемы.

Ключевое наблюдение из этого примера заключается в том, что, хотя квадрат является прямоугольником в геометрии, Square не является Rectangle с точки зрения ООП - Squareповедение несовместимо с Rectangle,

Другие вопросы по тегам