if S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e. an object of type T may be substituted with any object of a subtype S) without altering any of the desirable properties of the program
- Method parameter types are contravariant, i.e. if you override a method, the overriding method in the subtype must accept parameters of the same types or more general types as the overridden method.
- Method return types are covariant, i.e. the overriding method in a subtype must return the same type or a more specific type as the overridden method.
- Methods in subtypes must not raise any new exceptions that are not only raised by the overridden method in the supertype, except for exceptions whose types are themselves subtypes of the exceptions raised by the overridden method.
- Preconditions cannot be strengthened in a subtype, i.e. if you replace an object with a subtype, you cannot impose additional restrictions on the caller, since the caller doesn't know about them.
- Postconditions cannot be weakened in a subtype, i.e. you cannot relax guarantees that the supertype makes, since the caller may rely on them.
- Invariants must be preserved, i.e. if the supertype guarantees that something will always be true, then it must also always be true in the subtype.
- History Rule: Manipulating the object of a subtype must not create a history that is impossible to observe from objects of the supertype. (This one is a bit tricky, it means the following: if I observe an object of type S only through methods of type T, I should not be able to put the object in a state such that the observer sees a state that would not be possible with an object of type T, even if I use methods of S to manipulate it.)
Here is other ways to look at the LSP:
-
if I have an inspector who only knows and cares about T, and I hand him an object of type S, will he be able to spot that it is a "counterfeit" or can I fool him?
-
The only way that adding a new method can violate LSP is if this new method manipulates old state in such a way that is impossible to happen using only old methods.
https://en.wikipedia.org/wiki/Liskov_substitution_principle https://softwareengineering.stackexchange.com/questions/170138/is-this-a-violation-of-the-liskov-substitution-principle https://stackoverflow.com/questions/44442448/when-adhering-to-liskov-substitution-principle-lsp-can-a-child-class-implement