I am learning a lot about this principle (also thanks to two answers I received here) and would like to elaborate on another point that somebody mentioned.
1) Is the following a violation of LSP?
class Base
{
public virtual void UpdateUI()
{
//documented: immediately redraws UI completely
}
}
class Component: Base
{
public override UpdateUI
{
if (Time.Seconds % 10 ==0) //updates only every ten seconds
{
//drawing logic
}
}
}
In my understanding, the code description in the base class represents the contract, expected behavior, that is violated in the subtype.
2) Why breaking of behavior does not matter for weakening precondition?
class Human
{
public virtual void DoSomething(int age)
{
//precondition - age < 100
{
}
class Cyborg : Human
{
public virtual void DoSomething(int age)
{
//precondition - age < 200
{
}
The Cyborg class weakened the precondition, which is allowed. For valid arguments, substitution works well. Whenever I have a Human object, a Cyborg object can be used. But what if I have a test like this: Human(110) - must fail, argument needs to be < 100
When I substitute with Cyborg, the test will pass. I.e. the behaviour changed. Why is that allowed?