Interfaces and substitutable behavior
Liskov’s 1987 discussion distinguishes semantic type relationships from language mechanisms such as class inheritance. Inheritance can implement subtyping, but code reuse alone does not establish substitutability.
A stack and a queue may both offer add and remove operations, yet one is last-in-first-out and the other first-in-first-out. A client relying on removal order can distinguish them.
References: [1]
Requirements and guarantees
Eiffel’s contract-inheritance rules permit weakening preconditions and strengthening postconditions. A call allowed by the parent’s contract must not become invalid merely because a replacement object is used.
If a parent accepts every nonnegative amount, a child that additionally requires a minimum amount raises the entry requirement. Internal algorithms may differ while preserving the client-facing contract.
References: [2]
The specification defines the boundary
Class invariants constrain valid observable states and must also be preserved. Substitutability does not require identical representations or instructions; the specification identifies what matters to users.
Specifications therefore need meaningful promises about results and state changes. Passing a type checker is useful, but is not a complete proof that an implementation fulfills its behavioral contract.