I`m trying to understand the LSP History rule. I have read Wikipedia entry which states the requirement and provides an example:
History constraint (the "history rule"). Objects are regarded as being modifiable only through their methods (encapsulation). Because subtypes may introduce methods that are not present in the supertype, the introduction of these methods may allow state changes in the subtype that are not permissible in the supertype. The history constraint prohibits this. It was the novel element introduced by Liskov and Wing.
A violation of this constraint can be exemplified by defining a mutable point as a subtype of an immutable point. This is a violation of the history constraint, because in the history of the immutable point, the state is always the same after creation, so it cannot include the history of a mutable point in general. Fields added to the subtype may however be safely modified because they are not observable through the supertype methods. Thus, one can derive a circle with fixed center but mutable radius from immutable point without violating LSP.
In my opinion, there is a problem with this example. Inducing the subtype Mutable point
to the supertype Immutable Point
breaks the invariant requirement.
Invariants of the supertype must be preserved in a subtype.
Can you think of a more suitable example of a bad OO design that does not comply with the history rule but nevertheless satisfies the invariant requirement?
Alternatively can you provide another explanation for why this requirement is necessary?