admin管理员组文章数量:1200344
The Liskov substitution principle states that a piece of code should remain correct if a superclass is replaced with its subclass (paraphrasing). What I don't understand; Why do we care about this property? Does it make our code more reusable, flexible , or maintainable ?
I would appreciate an example piece of code that adheres to the principle and one that violates it when explaining the relevance of substitution property.
The Liskov substitution principle states that a piece of code should remain correct if a superclass is replaced with its subclass (paraphrasing). What I don't understand; Why do we care about this property? Does it make our code more reusable, flexible , or maintainable ?
I would appreciate an example piece of code that adheres to the principle and one that violates it when explaining the relevance of substitution property.
Share Improve this question edited Jan 21 at 21:05 Mark Seemann 233k49 gold badges447 silver badges773 bronze badges asked Jan 21 at 19:40 ariko stephenariko stephen 958 bronze badges2 Answers
Reset to default 3The Liskov substitution principle states that a piece of code should remain correct if a superclass is replaced with its subclass
If this was the only thing that the principle stated, it hardly makes sense to ask why we care about it. Consider what the opposite of that principle would mean: That a piece of code should not remain correct if a superclass is replaced with its subclass?
Who would want their software to be incorrect?
What the Liskov Substitution Principle (LSP) actually says is that a a subclass may widen preconditions and tighten postconditions, but not the other way around.
This makes good sense, if you think about it. Consider a simple method that takes an integer as input.
void Foo(int i)
If the superclass states that every integer i
is valid, then what would happen if a subclass tightened the precondition? You might, for example, implement a subclass that divides some number by i
. If you do that, however, the input value 0
would now cause a division-by-zero error in the subclass, and that error wouldn't happen in the superclass.
Client code relies on the contract published by the superclass, since it doesn't know which subclass it might be interacting with.
As the opposite example, imagine that the superclass has a precondition that says that i
mustn't be 0
. This means that no well-behaved client is going to call the Foo
method with a 0
argument. If you then implement a subclass that can handle 0
, no harm is done. Thus, you can widen the precondition, but not tighten it.
Similar considerations apply to postconditions, just in the opposite direction. Here, a subclass may tighten a postcondition, but not widen it.
You can see some realistic C# examples in my article The Liskov Substitution Principle as a profunctor.
Violation of the Liskov substitution principle leads to incorrect execution of the program.
Here is an example of such a violation:
class Rectangle {
private int width;
private int height;
public void setWidth(int width) {
this.width = width;
}
public void setHeight(int height) {
this.height = height;
}
public int area() {
return width * height;
}
}
class Square extends Rectangle {
@Override
public void setWidth(int width) {
super.setWidth(width);
super.setHeight(width);
}
@Override
public void setHeight(int height) {
super.setWidth(height);
super.setHeight(height);
}
}
// This code will not work correctly for instance of Square
void test(Rectangle rectangle) {
rectangle.setWidth(5);
rectangle.setHeight(10);
assertEquals(50, rectangle.area());
}
本文标签: oopUsefulness of the substitution property of the Liskov Substitution PrincipleStack Overflow
版权声明:本文标题:oop - Usefulness of the substitution property of the Liskov Substitution Principle - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738602853a2102174.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论