ruby – Square和Rectangle继承有什么问题?

前端之家收集整理的这篇文章主要介绍了ruby – Square和Rectangle继承有什么问题?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我已经阅读了一些关于使Square成为Rectangle类的继承类的做法的一些文章,这说明它违反了LSP(Liskov替换原则).我仍然没有得到它,我在 Ruby中做了一个示例代码
class Rectangle
    attr_accessor :width,:height
    def initialize(width,height)
        @width = width
        @height = height
    end
end

class Square < Rectangle
    def initialize(length)
        super(length,length)
    end
    def width=(number)
        super(number)
        @height = number
    end

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


s = Square.new(100)

s.width = 50

puts s.height

谁能告诉我它有什么问题?

解决方法

我并不总是热衷于Liskov,因为它似乎限制了你可以根据行为而不是“本质”继承的方法.在我看来,继承总是意味着“是一种”关系,而不是“行为完全像”一种关系.

话虽如此,the wikipedia article详细说明了为什么有些人认为这很糟糕,使用您的确切示例:

A typical example that violates LSP is a Square class that derives from a Rectangle class,assuming getter and setter methods exist for both width and height.

The Square class always assumes that the width is equal with the height. If a Square object is used in a context where a Rectangle is expected,unexpected behavior may occur because the dimensions of a Square cannot (or rather should not) be modified independently.

This problem cannot be easily fixed: if we can modify the setter methods in the Square class so that they preserve the Square invariant (i.e.,keep the dimensions equal),then these methods will weaken (violate) the postconditions for the Rectangle setters,which state that dimensions can be modified independently.

所以,看看你的代码和等效的Rectangle代码

s = Square.new(100)            r = Rectangle.new(100,100)
s.width = 50                   r.width = 50
puts s.height                  puts r.height

输出将在左侧为50,在右侧为100.

但是,在我看来,这是文章的重点:

Violations of LSP,like this one,may or may not be a problem in practice,depending on the postconditions or invariants that are actually expected by the code that uses classes violating LSP.

换句话说,如果使用类的代码理解行为,则没有问题.

底线,正方形是矩形的适当子集,对于矩形的宽松定义:-)

猜你在找的Ruby相关文章