I've just wondered if there is a difference between the IS-A (which is the UML terminology and OOP) and Liskov Substitution Principle (LSP)?
Actually, both are talking about the inheritance. So what is the main difference in practice?
Both terms describe the same "concept" in the end.
The Liskov substitution principle tells you: an inheritance relation between to classes B (base) and C (child) is sound when each and any usage of some object of type B ... can be replaced with an object of type C.
This means: B defines an API and a public contract - and C has to uphold these properties, too!
And IS-A amounts to the same thing: that some object of C is also a B.
The "difference" is: the LSP gives you exact rules that you can check. Whereas IS-A is more of an "observation" or expression of intent. Like in: you express that you wish that class C IS-A B.
In other words: when you don't know how to properly use inheritance, IS-A doesn't help you writing correct code. Whereas the LSP clearly tells you that something like:
class Base { int foo(); }
class Child extends Base { @Override double foo(); }
is invalid. According to LSP, you can only widen method arguments, and restrict return values.
int iValue = someBase.foo();
can't be replaced with
int iValue = someChild.foo();
because the foo()
method is widened in its result.
And a final thought: many people think that C IS-A B is the same as just writing down Child extends Base
. Yes. But this only tells the compiler that C extends B. It doesn't mean that the methods you use in C will follow the LSP and thus turn C into a real valid descendant of B.
C IS-A B requires more than "C extends B". To be truly valid, LSP has to be uphold!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With