“Subtypes must be substitutable for their base types.”1)
Object-oriented programming languages allow to derive subtypes from base types and subtype polymorphism allows to pass an object of a subtype where ever an object of the supertype is specified. Suppose
Q are types (i.e. classes or
Q is derived from
Q is the subtype and
P is the base type or supertype). A method
m requiring a parameter of type
P can be called with objects of type
Q because every object of type
Q is also an object of type
P. This is always true as typically object-oriented programming languages are constructed in that way.
But the programming language does not enforce that the subtype also behaves like the supertype. Method
m may work with an object of type
P but not with an object of type
Q. LSP demands that a subtype (
Q in the example) has to be constructed in a way that it behaves like the supertype if it is called through the supertype interface.
Q may have further methods and it may do additional things not observable by
m shall be able to safely assume that its parameter behaves like an object of type
P with respect to all observable state.
Q be types and
Q a subtype of
P. If LSP is not adhered to, there is an operation accessible through the interface of
P which behaves differently when called on
Q. So code which is written in terms of
P will not expect the behavior and will not work as desired.
See section contrary principles.
Barbara Liskov: Data abstraction and hierarchy
protectedfeatures for subclasses in general. But it should be inherently clear that subclasses in general may need this functionality without looking at a particular one.