里氏替换原理 - 如何建模正方形和矩形
可能的重复:
从矩形导出正方形是否违反里氏替换原理?
通过应用LSP,谁能给我一个Square和Rectangle的实现?
我读过《Head First Object-Oriented Analysis and Design》这本书,他们说如果Sqaure继承自Rectangle,它就违反了LSP,但没有正确的实现。
有人想尝试吗?
Possible Duplicate:
Is deriving square from rectangle a violation of Liskov's Substitution Principle?
By applying the LSP, can anyone give me an implementation of Square and Rectangle?
I have read the book - "Head First Object-Oriented Analysis and Design", they said if Sqaure inherit from Rectangle, it violated the LSP but does not have a proper implementation.
Anyone want a try?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果你让 Square 和 Rectangle 不可变,那么你就不会违反 LSP。
问题是,如果您可以独立更改矩形的宽度和高度,并且正方形是矩形,那么您可以将正方形更改为不是正方形。
If you make Square and Rectangle immutable, then you won't violate LSP.
The issue is if you can independently change the width and height of a Rectangle, and a Square is a Rectangle, then you can change a Square to not be a square.
我会说:不要
正方形是矩形的特殊情况。所以:使用矩形。目前还不清楚是否有任何充分的理由有一个独特的正方形类。
当然,这实际上取决于您对这些形状的用途。 LSP 是否满足取决于您对形状的操作。
I would say: Don't
A square is a special case of a rectangle. So: use rectangles. Its not clear that there is any good reason to have a distinct square class.
Of course, that really depends what you are doing with these shapes. Whether or not LSP is satisfied depends on the operations you have on your shapes.
您最好在构造函数中传递一个约束(
bool square
会这样做),将其存储为字段,并在计算期间检查字段(x、y、w、h?) '方形度”从而加快了这些计算的速度。您可以这样设置,如果设置了“方形”约束,则设置宽度或高度将导致另一个自动匹配。
set(x, y, w, h)
方法始终有效,但如果参数没有给出正方形,则会抛出IllegalArgumentException
或类似异常。You'd be better off with passing a constraint in the constructor (
bool square
would do) storing that as a field, and checking the fields (x, y, w, h?) during calculations for 'squareness' thus speeding elements of these calculations up.You could make it so that if the 'square' constraint is set, setting width or height would cause the other one to match automatically. The
set(x, y, w, h)
method would always work, but would throw anIllegalArgumentException
or such if the arguments didn't give a square.如果它们是不可变的,如上所述,那么它不会违反 LSP:
现在,如果您有一个采用百分比的
scale()
方法,您可以以符合 LSP 的方式增长矩形和正方形,但是当然,矩形上的grow()
方法需要两条被正方形覆盖的边才能正确运行,这会违反 LSP。If they are immutable, as stated above than it does not violate LSP:
Now if you had a
scale()
method that took a percentage you could grow the rectangle and square in an LSP-compliant way, but agrow()
method on rectangle that took two sides that's overridden by square to behave correctly, of course, would violate LSP.克林顿说得最好:这取决于是什么的定义
正方形是矩形这一不可动摇的直觉来自我们的数学训练。数学对象是不可变的且无身份的。如果您的程序确实在数学意义上对正方形和矩形对象进行建模,那么 Square 应该是 Rectangle 的子类型,并且它们应该是不可变的。任何适用于矩形的数学运算也适用于正方形。
但是,您的程序可能不会对数学对象进行建模。也许您正在对图形屏幕对象进行建模。其中有数学方面的内容,但还有更多。然后我们就陷入混乱了。考虑到您想要对矩形进行的所有操作,也许最好将矩形设计为正方形的子类型。那么这完全违背了我们的数学直觉,我们不希望我们的设计出现这种混乱。
这是一个可怕的事实:OOP 很无聊。你可能认为一些超级聪明的人做了一些宏伟的研究并想出了这个万能的编程模型。每个谜题都有一个完美的解决方案,只是你不知道它,因为你还没有足够好地理解这个神圣的启示。人们比宗教敌人更热衷于讨论 OOP,互相抛出大词和抽象概念,引用没人真正理解的古代文本中的原理和惯例。
Clinton put it the best: it depends on what the definition of is is
The unshakable intuition that a square is a rectangle comes from our mathematical training. Mathematical objects are immutable and identity-less. If your program indeed is modeling square and rectangle objects in the mathematical sense, then Square should be a subtype of Rectangle, and they should be immutable. Any mathematical operations that applicable to Rectangle are applicable to Square.
However, your program may not be modeling mathematical objects. Maybe you are modeling graphic screen objects. There are mathematical aspects in them, but then there are more. Then we are in a mess. Maybe it's better to design Rectangle as subtype of Square, considering all the operations that you want to put on them. Then it's completely against our mathematical intuition, and we do not want that kind of confusion in our design.
This is a horrible truth: OOP is meh. You may have thought that some super smart people did some grandiose research and came up with this omnipotent programming model. For every puzzle there is a perfect solution, you just don't know it because you haven't become good enough in understanding this divine revelation. People argue about OOP with more zeal than religious enemies, throwing big words and abstract concepts at each other, quoting principles and conventions from ancient texts which nobody really understands.