If S is a subtype of T, then objects of type T in a program may be replaced with objects of type S without altering any of the desirable properties of that
Sounds confusing? It sure does to me at least.
Here is an easier version
If you have sub-classed a given class- in that case any program that uses your parent class via a pointer or a reference – should continue to be able use any of the sub class that it may get instead of the Parent class- without any change in behaviour.
Now why is this important ?
Polymorphism was designed to provide a run-time binding that would make possible to use a different set of behavior depending upon the context. Which is all nice and cool- except that when you switch the behavior with another behavior which is semantically not compatible with the behavior of the parent class
Example- when its violated
We have a class Product. This has a method- order().The behavior of this method is that it places an order with the vendor.
Now your inventoryControl System uses many Products and uses this method to order goods.
We decide to introduce a new range of products- Guns.
And since this needs authorization- the Guns class instead of placing the order with the vendor- sends an email to the Manager.
This would serve the purpose of informing the Manager that someone wants to purchase a Gun and may initiate a sequence of events leading to that. But it would create confusion for the system which would be waiting for a conformation from the vendor that the order was placed or may start a check as to why the Vendor hasn’t received an order yet…
Whenever you extend a class and override an already implemented method- watch out.You need to make sure that you are not violating the contract established by the Parent class. In contrast – its OK to override abstract methods.
Design by Contract (Dbc)
This principle leads to a very parallel concept- Design by Contract
What this basically says is – that whenever you subclass-
A) You should not impose newer or stricter preconditions. Example : The method in the parent class accepts an int type parameter and has no problem with a negative value. If the method in the child class is unable to handle negative parameters while the parent class can- we are violating Dbc.
B) You cant weaken the post-conditions. Example: The method in the base class- places an order with a vendor and send you a confirmation email. If the method in your child class- simply places an order- but fails to send a confirmation email- it is violating Dbc.
On the same lines- a method in the child class- cant throw an exception- which is not in the throws class of the Prent class. The obvious reason is that the programs using references to parent class- would not be coded to handle this exception .
Who do we thank for this ?
Barbara Liskov: http://en.wikipedia.org/wiki/Barbara_Liskov
Interactive Software Engineering for Design by contract