正方形继承长方形违反liskov原则?
几乎所有的将Liskov原则的文章都提到了“正方形继承长方形违反Liskov原则”。
但都说的不清不楚的
假设我有如下的两个类,请问哪个地方违反了Liskov原则呢?
public class Rectangle ...{
protected double width;
protected double height;
public double getWidth() ...{
return width;
}
public void setWidth(double width) ...{
this.width = width;
}
public double getHeight() ...{
return height;
}
public void setHeight(double height) ...{
this.height = height;
}
public double calcSize() ...{
return this.height * this.width;
}
}
public class Square extends Rectangle ...{
@Override
public void setHeight(double height) ...{
setEdge(height);
}
@Override
public void setWidth(double width) ...{
setEdge(width);
}
@Override
public double getHeight() ...{
return getEdge();
}
@Override
public double getWidth() ...{
return getEdge();
}
public double getEdge() ...{
return this.height;
}
public void setEdge(double edge) ...{
this.height = edge;
this.width = edge;
}
}
[解决办法]
这样看来好像是 Robert C.Martin 曲解了里氏替换原则的本意。
[解决办法]
不知道什么叫“liskov原则”,但
《effective C++ 第三版》里面讨论过这个问题 可以参考p154-p155
其大致的解释为:
一些可以运用在矩形上的方法(比如单独增加矩形的长或者宽)却不能运用在正方形上(因为正方形必须长和宽一致)。
简单的说:
“能够施行于base class对象上的每件事情,也可以施行于derived class对象身上”
[解决办法]
这些我不是很清楚
但也up一下
------解决方案--------------------
“能够施行于base class对象上的每件事情,也可以施行于derived class对象身上”
____________________________________________________________________________
这个就是“里氏替换原则”。
[解决办法]
我觉得根本没违反啊!长方形的长和宽相等不就是正方形吗?正方形是长方形的特例,完全可以继承。
[解决办法]
关键是子类扩展父类的时候,只能增加字段和方法,而不能增加约束。
长和宽必须相等是对父类中两个字段的约束,而在子类无法扩展这种约束,这算是目前oo语言的局限性。期待下一代oo语言解决。
[解决办法]
学习下~~~~~~~
谢谢上面的同志们
[解决办法]
我认为有意义的,里氏替换原则是面向对象设计原则中五大原则之一。
要设计比较好的应用,至少要符合这些原则的。
[解决办法]
接楼上
不过好像我们在设计的时候, 不应该刻意地去想这个原则, 那个原则...
原则仅仅是原则, 用来指导我们, 而不是左右我们...
[解决办法]
接楼上楼上
原则只是界定了一个规范,让我们可以看到一个好的系统应该如何去实现的,而且这些原则都是一些前辈经验的总结,我们应该汲取他们的经验的,在软件设计时我认为很有必要考虑一下的。