考虑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 变为紫色:
square
对象的是Square
类的实例,rectangle
对象是Rectangle
类的实例
width=
是两者中的一种方法
width=
中的square
中的width=
无法替换为rectangle
中的Rectangle
因为它不会将高度设置为'square'中定义的高度。
这种思维方式我错了吗?
此外,我学会了使用紫罗兰width=
类中'width ='方法的联系来分析这个问题:
@width
,
前提条件:@height
和@width
有一些价值。
postconditon:@height
更改为新值,Square
保持不变。
表示@height
类
前提条件:与上述相同
postconditon:'@ width'更改为新值, @height
更改为新值
根据原则:不再需要,承诺不少
DBC
已更改,因此未履行承诺,因此无法继承
有没有人可以通过{{1}}?
给我一些关于我分析此问题的方法的建议答案 0 :(得分:2)
LSP仍然适用,即使在像Ruby这样的动态类型语言中也是如此。你的推理:
我总是可以使用以下方法检查对象的类:
rectange.class
在这种情况下,如果Ruby中的代码将返回
Square
,那么我不会将其视为Rectangle
。
不是特定于Ruby;实际上,您也可以在Java中检查变量的实际类。这样做并不能解决这个问题。
此示例的关键观察是,虽然正方形是几何体中的矩形,但从OOP角度来看,Square
不是 Rectangle
- { {1}}的行为与Square
的行为不相容。