According to Is this a violation of the Liskov Substitution Principle?, as I understand, the top answer currently says the code below is violating "Liskov Substitution Principle":
public class Task{
private boolean isStarted;
private boolean isClosed;
public void close(){
isClosed=true;
}
}
public class ProjectTask extends Task{
public void Close(){
if (this.isStarted)
throw new Exception("Can't close a started ProjectTask");
super.close();
}
}
However, I'm not asking why it is violating "Liskov Substitution Principle", what I want to ask is, why would "Preconditions can't be strengthened in a subtype" and "Postconditions can't be weakened in a subtype" be 2 separate rules. Isn't they are the same? According to answer https://softwareengineering.stackexchange.com/a/187615/432039 that intercept the example above:
Preconditions can't be strengthened in a subtype: close() works on both started and non-started Task originally, but the subtype requires non-started Task, this is strengthened pre-conditions.
Postconditions can't be weakened in a subtype: The base class used to guarantee all Task would be closed after calling close(), but the subtype ProjectTask can be leave unclosed even after calling close() because of throwing exception, this is weakening post condition.
It seems that when "Preconditions strengthened" occurs, "Postconditions weakened" mostly also occurs, is it true? If not, what is the different between them? Why list 2 rules separately? Is there any case that postconditions are weakened but preconditions are not strengthened (or vice versa)?