这样可以解决Liskov替代方矩形违反问题吗? [英] Does this solve the Liskov Substitution square-rectangle violation?
问题描述
我对SOLID设计原则非常陌生.我在理解上遇到的问题之一是违反Liskov替代原理的正方形"示例.为什么正方形的高度/宽度设置器会覆盖矩形的高度/宽度设置器?当存在多态性时,这难道不是问题的原因吗?
I'm very new to the SOLID design principles. One thing I had problem with understanding is the "Square-rectangle" example of a Liskov Substition Principle violation. Why should the Height/Width setter of a Square override the ones of a Rectangle? Isn't this exactly what's causing the problem when there's Polymorphism?
不删除它可以解决问题吗?
Doesn't removing this solve the problem?
class Rectangle
{
public /*virtual*/ double Height { get; set; }
public /*virtual*/ double Width { get; set; }
public double Area() { return Height * Width; }
}
class Square : Rectangle
{
double _width;
double _height;
public /*override*/ double Height
{
get
{
return _height;
}
set
{
_height = _width = value;
}
}
public /*override*/ double Width
{
get
{
return _width;
}
set
{
_width = _height = value;
}
}
}
class Program
{
static void Main(string[] args)
{
Rectangle r = new Square();
r.Height = 5;
r.Width = 6;
Console.WriteLine(r.Area());
Console.ReadLine();
}
}
输出为预期的30.
推荐答案
想象用户正在GUI应用程序中实现边界框,类似于:
Imagine the user is implementing a bounding box in a GUI application, similar to this:
他们希望通过Rectangle
类表示此蓝色框,以便在用户单击&向下拖动它的高度会增加;如果用户向右拖动,其宽度将增加.
They want to represent this blue box by a Rectangle
class, so that if the user clicks & drags down its height will increase; if the user drags right, its width will increase.
LSP指出,无论您在哪里使用客户端的超类(矩形),客户端都应该能够在不破坏Rectangle的业务逻辑的情况下使用派生类(Square),即,用户应该能够为另一个& amp ;他们的其余代码不应中断.
LSP states that a client should be able to use a derived class (Square) wherever you would use its superclass (Rectangle) without breaking the business logic of Rectangle — i.e. a user should be able to sub in one for the other & the rest of their code shouldn't break.
但是以下内容彼此不兼容:
But the following are incompatible with each other:
- 这是Rectangle的后置条件,它的setter方法不会引起副作用(即
setWidth
不应影响高度) - 正方形的逻辑固有的是宽度总是等于高度.
- It's an assumed post-condition of Rectangle that it's setter methods won't cause side effects (i.e.
setWidth
shouldn't affect the height) - It's inherent to the logic of a Square that its width will always equal its height.
如果程序员使用Square而不是Rectangle,则上面的假设将不起作用,就像用户向下拖动一样,该框在水平方向上会变大&同时垂直放置.
If the programmer used Square instead of Rectangle, their assumption above wouldn't work, as if the user dragged down, the box would get bigger horizontally & vertically at the same time.
Square/Rectangle示例的麻烦之处在于,我们一开始对Rectangle的假设过多.矩形可以具有与其高度不同的长度,但这是特定类型的矩形(长方形矩形)的属性.
The trouble with the Square/Rectangle example is that we're assuming too much about Rectangle to begin with. A rectangle can have a different length to its height, but this is a property of a specific type of rectangle (an oblong rectangle).
一个正方形是一个矩形,但是一个正方形不是一个长方形.如果我们想假设关于Rectangle
类的椭圆形的行为(宽度和高度可以不同),那么Square
类从此扩展是没有意义的.
A square is a rectangle, but a square is not an oblong rectangle. If we want to assume the behaviour of an oblong about our Rectangle
class (that it's width & height can differ), it's then doesn't make sense for our Square
class to extend from that.
这篇关于这样可以解决Liskov替代方矩形违反问题吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!