The following are some examples I've collected that demonstrate how Liskov Substitution Principle could be violated.
NOTE: Before continue if you need more details about the definition of Liskov Substitution Principle refer to its Wikipedia page Liskov substitution principle.
NOTE: The below examples don't cover all the possibilities of violating LSP.
Examples:
Throwing a
NotImplementedException
from a derived/implementation class is a sign that the parent-child relation is not following LSP. Here in the code snippetIBird
class cannot representDuck
as it has no definition for flying.
Hiding a
virtual
parent method in a child class using thenew
keyword also violates LSP. In the code below when the declaration type is changed from the base classEmployeeAnnualBonus
to the derived classManagerAnnualBonus
the value of the annual bonus is changed, which means that they cannot be substitutable without altering the expected result.
(Hereoverride
keyword should be used instead.)
Returning a value of a type that has restrictions that are unknown from the method's signature. Such as returning a value of type
ReadOnlyCollection
from a derived class' method while the return type in its signature isICollection
. The code below demonstrates how this approach is making unexpected behavior for the code consumer.
Adding an implementation for a derived method in a way that violates the system code's policy or conventions (if there is any); like when a derived method returns a
null
value for a list when there is a convention not to returnnull
for empty collections but instead to return initialized collections with zero items count.
Conclusion:
It's recommended to keep code components (classes or projects) separated and to depend on abstractions instead of concrete implementations, and that makes applying Liskov Substitution principle more important. The implementation of the derived classes may not be known for the code consumer or at design time and implementing a method that returns a value or accepts parameters in a way that is unclear from its interface (or base class) will mislead who calls that code which in turns may break the code execution or result in unexpected behaviors at run time.
Top comments (0)