My understanding of the Liskov substitution principle is that some property of the base class that is true or some implemented behaviour of the base class, should be true for the derived class as well.
I guess this would mean when a method is defined in a base class, it should never be overrided in the derived class - since then substituting the base class instead of the derived class would give different results. I guess this would also mean, having (non-pure) virtual methods is a bad thing?
I think I might have a wrong understanding of the principle. If I don't, I do not understand why is this principle good practice. Can someone explain this to me? Thanks
Subclasses overriding methods in the base class are totally allowed by the Liskov Substituion Principle.
This might be simplifying it too much, but I remember it as "a subclass should require nothing more and promise nothing less"
If a client is using a superclass ABC
with a method something(int i)
, then the client should be able to substitute any subclass of ABC
without problems. Instead of thinking about this in terms of variable types, perhaps think about it in terms of preconditions and postconditions.
If our something()
method in the ABC
base class above has a relaxed precondition that permits any integer, then all subclasses of ABC
must also permit any integer. A subclass GreenABC
is not allowed to add an additional precondition to the something()
method that requires the parameter to be a positive integer. This would violate the Liskov Substitution Principle (i.e., requiring more). Thus if a client is using subclass BlueABC
and passing negative integers to something()
the client won't break if we need to switch to GreenABC
.
In reverse, if the base ABC
class something()
method has a postcondition - such as guaranteeing it will never return a value of zero - then all subclasses must also obey that same postcondition or they violate the Liskov Substitution Principle (i.e., promising less).
I hope this helps.