LSP | Subclass overrides method but changes semantics | Check overridden methods: does the subclass return a fundamentally different type, change the meaning of the return value, or produce side effects the parent does not? Compare method signatures and doc comments. | Major |
LSP | Subclass throws exception parent doesn't declare | Look for overridden methods that throw exceptions not present in the parent's throws clause or documented contract. In dynamic languages, look for raise/throw in overrides where the parent method doesn't throw. | Major |
LSP | Subclass ignores or no-ops parent behavior | Look for overridden methods with empty bodies, pass, return null, return, or // not implemented comments. The subclass is refusing the parent's contract. | Minor |
LSP | instanceof/type checks after polymorphic call | Search for instanceof, is_a, typeof, type(), is checks on objects that should be used polymorphically. If code calls a method on a base type and then checks the concrete type, it signals broken substitutability. | Major |