Substitutability is a principle in object-oriented programming stating that, in a computer program, if S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e., an object of type T may be substituted with any object of a subtype S) without altering any of the desirable properties of the program (correctness, task performed, etc.).
If your Ugly Duckling doesn't quack like a duck, or is only raised by a duck but is not one itself (a has-a relationship, ergo composition!)... it probably shouldn't be a subclass of Duck. But if it does those things, and you gain more than you lose from the simplicity of passing around simple objects (okay, the analogy has completely frayed here), it should!
The interview[0] with Barbara Liskov about the principle is also really interesting.
Although it may seem a little strange these days, in those days it was a long way from the
east coast to the west coast, and of course we had no conference calls in those
days too. That whole business about object-oriented programming was
developing on the west coast and on the east coast we were mostly working on
data abstraction, and the two worlds were kind of separated. So I knew the
name, but we didn’t run into each other at conferences and there wasn’t much
crosstalk going on.
In the 1980s, I was asked to give a keynote at OOPSLA, which I think it was
maybe the second OOPSLA. It hadn’t been in existence very long. So I decided
that this was a good opportunity to learn about what was going on in object-
oriented languages. So I started reading all the papers and I discovered that
hierarchy was being used for two different purposes. One was simply
inheritance. So I have a class, it implements something, I can build a subclass, I
can borrow all that implementation, change it however I want, add a few extra
methods, change the representation. Whatever I want to do, I just sort of borrow
the code and keep working on it.
The other way it was being used was for type hierarchy. So the idea was that the
superclass would define a supertype, and then a subclass would extend this to
become a subtype. I thought this idea of type hierarchy was very interesting, but
I also felt that they didn’t understand it very well. I remember reading papers in
which it was clear they were very confused about it, because one in particular
that I remember said that a stack and a queue were both subtypes of one another.
This is clearly not true because if you wrote a program that expected a stack and
you got a queue instead, you would be very surprised by its behavior. The
difference between LIFO and FIFO is a big deal.
This led me to start thinking about “What does it really mean to have a
supertype and subtype?” And I came up with a rule, an informal rule which I
presented in my keynote at OOPSLA which simply said that a subtype should
behave like a supertype as far as you can tell by using the supertype methods.
So it wasn’t that it couldn’t behave differently. It’s just that as long as you
limited your interaction with its objects to the supertype methods, you would get
the behavior you expected.
[...]
Meanwhile I was working on distributed computing, I was particularly interested
in viewstamped replication and some of the other work that was going on in my
group at the time, and I wasn’t really thinking about this until sometime in the
’90s when I got an email from someone who said, “Can you tell me if this is the
correct meaning of the Liskov substitution principle?” So that was the first time
I had any idea [laughs] that there was such a thing, that this name had
developed.
Comments
A comment in the Stack Overflow post that the OP links to led me to https://en.wikipedia.org/wiki/Liskov_substitution_principle which seems to be far more useful a concept to know than the OP:
If your Ugly Duckling doesn't quack like a duck, or is only raised by a duck but is not one itself (a has-a relationship, ergo composition!)... it probably shouldn't be a subclass of Duck. But if it does those things, and you gain more than you lose from the simplicity of passing around simple objects (okay, the analogy has completely frayed here), it should!
The interview[0] with Barbara Liskov about the principle is also really interesting.
[...]
[0] https://amturing.acm.org/pdf/LiskovTuringTranscript.pdf page 29