
Goodbye, shitty "Car extends Vehicle" object-orientation tutorial - sebkomianos
http://lists.canonical.org/pipermail/kragen-tol/2011-August/000937.html
======
d0m
Heh, I agree somewhat that the Duck>Animal is a bit annoying.. but this:

    
    
      Here’s an example that I think would be better to use instead: the
      `Visible` hierarchy in [Pygmusic][], which is a kind of software drum
      machine.  A `Timer` is a horizontal strip on the screen with a stripe
      racing across it. A `NumericHalo` is a spreading ripple on the screen
      that fades. A `Sound` is a thing on the screen that makes a sound when
      a `Timer`’s stripe hits it. A `Trash` is a thing that deletes `Sound`s
      when you drop them on it. They all inherit from `Visible`, which
      represents things that can be drawn on the screen and perhaps respond
      to mouse clicks or drop events, but they do different things in those
      three cases. In addition, the `Trash` and `Sound`s are subclasses of
      `ImageDisplay`, because the way they handle being drawn is simply to
      display a static image, so that code is factored into a superclass.
    

Is by far worst.. The goal of the Person or Duck is to pick a _trivial_
example to explain some concept. Of course you're not building Sim city and
that it will be totally different in real apps.

Also, it's true that inheritance is often the wrong solution and could
arguably be said that it create more problems than it solves. However, before
understanding all the pitfalls and the why/why not of inheritance, you first
need to _understand_ what inheritance is!

So, instead of _shooting_ someone who give an example with a Duck to explain
OO, let just say that this tutor should say beforehand "Let's take a trivial
example to understand the concepts of OO. Later on, we'll see why this is not
always the preferred solution."

~~~
kragen
Probably if you have a trivial piece of code, you don't need inheritance to
help you structure it. But you're right that we need a smaller example than
the entire class hierarchy of Pygmusic. What do you think would be the
smallest sensible example?

If your objective is only to explain _what_ inheritance is rather than _why_
someone would use it, you could probably write two classes and three methods:

    
    
        class A:
            def z(self):
                print "z " + self.y()
            def y(self):
                return "Ay"
    
        class B(A):
            def y(self):
                return "By"
    
        A().x()
        B().x()
    

But I really think that most people will find a program easier to understand
if it's not completely abstract like that — if it reflects some kind of
intentional process where a programmer was trying to achieve something. But in
order to explain inheritance in such a context, you need a program where
inheritance makes things better instead of worse. What do you think is the
simplest possible piece of code that would do that? I am thinking of a very-
much-cut-down version of Pygmusic with only two drawable objects.

~~~
spc476
Device drivers. You have a base class, device, which supports at the minimum,
read() and write(). Then you subclass to block and character devices, and so
from there. It's a real world example (Unix does it, although in C) and it's
simple enough to explain the concepts.

~~~
jrockway
But delegation is a better solution than inheritance for this, i.e. the
printer driver class takes a character device instance _as a parameter_.
Delegate the character device's read and write methods to the printer driver's
class, make the printer driver do the same interfaces, and done. Now you have
something that composes better than inheritance and substitutes anywhere you
needed a character device.

------
jeffreymcmanus
> You can’t add code to ducks.

You do if you are creating a piece of software to track ducks.

I don't get the impression that the person who wrote this ever had to
seriously teach software development to software developers. Simplistic
metaphors are used so frequently for this kind of thing because it prevents
the learner from having to ascend more than one conceptual hurdle at a time.
The alternative that he's proposing (learning inheritance in terms of some
obscure drum machine software) would imply that the learner spend half their
time digesting how this drum machine works, then the rest of their time
(assuming they're still awake) figuring out how that relates to inheritance.
It isn't helpful.

~~~
haberman
You can explain is-a using examples that actually make sense to model using
inheritance, like a set of game objects that have an interface like:

    
    
        class GameObject {
         public:
          // Called every frame to update the object's logical state.
          void Update(GameState* state);
    
          // Called to draw the object.
          Draw(GraphicsContext* context);
        }
    
        class EnemySpaceship : public GameObject { /* ... */ };
        class SpaceDebris : public GameObject { /* ... */ };
    

The point is to move the discussion into the practical reasons for introducing
inheritance, rather than to make it a pointless ontological exercise of
whether a Square is-a Rectangle or vice-versa.

~~~
fleitz
Most of the benefits of OO programming come from abstracting the machine /
concerns (eg. MVC) rather than modeling the domain. (eg. Cars / Ducks / etc).

I know it's just an example but it raises several important questions:

Why does the GameObject need to know how to render itself?

Why does the GameObject update the GameState which the GameObject is
ostensibly also a part of?

Does updating the GameState directly affect the ability to separate concerns
as to whether the GameState being modified is local vs. remote?

When you start modeling domains it leads very easily to situations where you
have hardcoded permissions for the Manager class instead of bothering to
implement a permissions system. Or you have a CEO class that's a singleton.
(Hopefully, your code doesn't have to work at RIM)

The code savings from

    
    
      class DeathStar2 : DeathStar {
        public override FatalFlaw(){}  
      }
    

is going to pale in comparison to

    
    
      class DeathStar2 : Object {
        acts_as_travelling_salesman
        has_many :laser_turrets, :max => 1024
        has_many :tie_fighters, :max => 2048
      }
    

when applied over many many systems and objects. Modeling domains is to
modeling concerns as algebra is to calculus. Most things in life despite their
appearances are not hierarchical and thus do not fit well when modelled
explicitly using a class hierarchy. Showing people how to model a domain is
easy but virtually useless, showing people how to model concerns is hard but
is where the big payoffs are.

~~~
jeffreymcmanus
Code savings isn't a reasonable goal of OOP. Information-hiding (in which you
take an arbitrarily-complicated method and abstract it behind a class) is.

~~~
fleitz
When you give people inheritance all they see is hierarchies and when you give
them information hiding systems all they see is access control.

One should not be able to find trade secrets by grepping for "private", nor
reproduce a companies org chart by a class inheritance graph.

------
SingleShot
I disagree with the arguments in general and find that modeling real world,
common items is much more illuminating from a teaching/learning point of view.
It would be an ridiculously long post to explain why, but here is an example
picking one of the author's bullet points: "Penguins don’t implement the fly
method that can be found in birds."

Should bird even have a fly method? Only if all birds fly. And the application
will have penguins, so the answer is "no". This doesn't make the Duck extends
Bird example a bad thing though. It points out that if you do shallow domain
analysis, you will end up with a poor OO design where you shoehorn things like
"fly" into penguins for example.

If some birds fly and some don't, some swim and some don't, some burrow and
some don't, etc. you might implement this with "mix in" interfaces like
"Flyer", "Swimmer", "Burrower", etc. This is a good lesson in how one can
distribute different behaviors across a class hierarchy without polluting the
common base interface of the hierarchy (i.e. without forcing all birds to
fly). However, this burns the behavior into the concrete classes, prevents
things like modeling the fact that baby (or dead) birds cannot
fly/swim/burrow, and does not allow for sharing different fly/swim/burrow
implementations across bird implementations (in languages like Java anyway).
In other words, it shows why inheritance can be a good choice, and also a bad
choice.

A common solution to this would be to use two hierarchies - one is the bird
hierarchy that all birds implement (with behaviors like "preen feathers"). The
other is the behavior hierarchy that all behaviors implement. Birds "contain"
a list of behaviors. Code that operates on birds knows the bird interface has
methods that make sense for all birds. Code that operates on behaviors like
fly/swim/burrow would have behaviors passed in, or perhaps ask the animal in
question "do you know how to fly?" and if yes, ask for its fly behavior. There
are many variations on this, but the point is that there is a separation of
concerns: bird concerns and behavior concerns. This helps teach the trade-off
between inheritance and containment (e.g. behaviors not burned in through
inheritance can be added/removed over time, for example, when a baby bird
learns to fly).

The point though is that this kind of example (Duck extends Bird) helps one
understand how to model real world items so they match the domain, to learn
about separation of concerns, learn the pros/cons of inheritance/containment,
design patterns, and perhaps most importantly, do so using concepts most
people will more readily understand (cars or birds or people).

~~~
azov
Indeed.

The example with Birds, Ducks, and Penguins is much more colorful and fun then
example with GUI widgets. It sticks. Students will remember ducks & penguins,
but fall asleep before you even finish describing that boring GUI system.

Plus, nothing prevents you from using the same fun example to illustrate the
second point. E.g. you can show that while penguin _is a_ bird in real world,
in your application Penguin might actually inherit from Pinniped, because it
_behaves like_ one (and it's "behaves-like", not "is-a" that we care about).

~~~
wlievens
If a CS student falls asleep when you talk about GUI systems, they're not in
the right class.

I didn't need fluffy birds and colorful metaphors to get into this passion of
mine.

The audience doesn't deserve to be patronized like that.

------
thaumaturgy
Way back when I was first learning OOP, the typical "car extends vehicle"
examples caused me not to see the practical point of OOP for a long time. I
_still_ resist using object-oriented approaches except in cases where the code
demands it. (A feature, not a bug?) And, these days, if I do use OOP in places
in the code, it's for encapsulation -- which is only a _style_ consideration
-- so the "car extends vehicle" example still doesn't apply.

I think a simple example from GUI programming would do much better. How about
window classes? I did something like this recently:

    
    
        class Window {
            public method show()
            public method title(newTitle)
            public method close()
        }
    

Easy enough. What if I want a modal window though? Almost everything in it
would be the same as a regular window, except I might need to do some things
slightly different for show()ing and close()ing the window. Aha! A perfect
example of an appropriate time to create a subclass:

    
    
        public class ModalWindow extends Window {
            public method show()
            public method close()
        }
    

Programming tends to attract practical individuals. I think teaching "car
extends vehicle" then is usually going to cause one of two results: either a
student that then uses that approach all the time, even in cases where it's
not warranted, because they don't understand when it's appropriate and when
it's not; or a pragmatic student that resists using it because the given
examples don't apply to anything that they're actually going to have any
chance of working on.

~~~
yoyar
I don't think so. In a windowing library you would do better to have the
IWindow interface and have both Window and ModalWindow implement IWindow.
Decorator then is appropriate so that ModalWindow can wrap Window and add the
desired functionality. I would not subclass Window in this case. This leaves
Window and ModalWindow totally substitutable and totally decoupled. If you
extend you couple Window and ModalWindow. Less coupling will likely serve you
better.

I eschew inheritance except for when two objects or libraries are very much
the same thing but the implementations are different. Just an example, where I
might want to have the opportunity to use two different PDF libraries.

Further, there's a case where a number of objects share some common methods
and you may decide to implement an AbstractWindow where those methods can
live. But, you may find that Aspect programming works better in that case.

Generally, and perhaps surprisingly you shouldn't use inheritance in most
cases. But inheritance is nonetheless a very important part of OOP.

~~~
mweatherill
Why would you want inheritance for different PDF libraries? This seems like
interface to me - the DOM interfaces are an appropriate analogy.

~~~
yoyar
Quite right. I didn't express that very well. An interface is appropriate with
implementations for each separate library.

------
mcphilip
The only situation where I could see not wanting to hear the car extends
vehicle example of inheritance is in an interview where you want the candidate
to give a practical example of inheritance. I see nothing wrong with using an
example even a child could understand as a first stab at explaining
inheritance.

Fairly annoying how quickly a mostly useless rant such as this has jumped to
the top of HN.

------
dustingetz
He asks for a simpler example. How about a collections api? Start with array,
then linked lists, then functioms like contains and filter and which need an
iterable interface, then different types of linked list, then add hashmap
where you iterate keys, then different types of map e.g. linked map. This is
all data structures 101 material anyway! After this primer, a simple GUI
toolkit isn't as far out of reach.

------
MarkMc
I think the best introduction to object oriented design is shown in the first
chapter of Martin Fowler's book "Refactoring" _. He gives the example of a DVD
rental shop that has to calculate the rental fee based on the type of DVD: \-
A New Release is $3 per day \- A Children's DVD is $1.50 for three days, then
$1.50 per day after that \- A Standard DVD is $2 for two days, then $1.50 per
day after that

_ [http://www.amazon.com/Refactoring-Improving-Design-
Existing-...](http://www.amazon.com/Refactoring-Improving-Design-Existing-
Code/dp/0201485672)

~~~
jrockway
The rest of that book, unfortunately, is stuff like: "To move code from one
file to another, follow these simple steps. Step 1: Delete the code from the
source file. Step 2: Add that code to the destination file. Step 3: Update
references to the code in (1) to point to (2). Step 4: Recompile your project
and fix the parts that don't compile."

What insight!

------
perlgeek
I've been working on writing a programming book for quite some time now, and I
can tell you that coming up with good examples is really hard.

For me, a good example meets as many as possible of the following demands (in
no particular order).

An example should

* demonstrate the feature or concept under discussion

* be short - shouldn't be more than half a page to a page

* solve a problem that the reader can easily understand

* solve an interesting problem

* not use unrelated features of the language or library that haven't been introduced yet

* should avoid complexity unrelated to the feature or concept under discussion

* should be as close as possible to what one would use in "serious" (ie non-teaching) programming

I found that i spent about as much time searching for good examples as
actually writing text or code for the book. I'm pretty happy with some of the
examples (for example the chapter on grammars parses JSON, which is rather
real-world, but not too complicated), some of them still fail most of the
demands given above.

(If you're curious, grab the latest PDF from
<https://github.com/perl6/book/downloads> \-- it's still very much a work in
progress).

------
5hoom
One of the first examples of OOP I encountered was the old 'shape' hierarchy
demonstration: 'shape' is a base class. 'rectangle' is a new class that
inherits from shape. 'square' inherits from 'rectangle', etc.

It demonstrates the ".. is a .." relationship that inheritance describes
perfectly.

This is a pretty common way to introduce OOP as it draws on stuff we all know
intuitively. The example proposed with a bunch of drum machines concepts,
trash, timers & stripes or whatever is so mind bogglingly obscure for most
people that I'm sure they would have checked out long before the actual OOP
lesson begins.

Not sure what the point is.

Oh, and btw, just because you might not ever need to represent a 'duck'
object, doesn't mean that it is a stupid example. Say I write a game with a
bunch of actors, I might have a base actor class, a bird class that extends
that, and a duck class that extends that. Bam, legitimate use for a 'duck'
object. There's probably a lot more people wanting to write "a clone of the
sims" than "an intractably obscure drum-machine".

~~~
kragen
> 'square' inherits from 'rectangle', etc. ... It demonstrates the ".. is a
> .." relationship that inheritance describes perfectly.

Your comment is a perfect example of why this is a terrible way to teach
object-oriented design: if your squares and rectangles are _mutable_ , as they
usually are in the old shape-hierarchy demonstration, you've just violated the
LSP and introduced a subtle bug into your program, _in the very first line of
your comment_. If you understood object-oriented design, you wouldn't do that.
You've been tricked into thinking you know how to do object-oriented design,
but your sense of competence is an illusion.

For what it's worth, although I don't have any real experience teaching other
people to program, I've found that animated graphics that make sounds hold the
attention of nontechnical people a lot better than abstract hierarchies of
Platonic geometric shapes. I haven't compared them with bird-flocking
simulations.

------
silverlake
Depends on the audience. If you're using the "Car : Vehicle" example, you're
probably explaining the basics of OO to a newbie. I think that's a fine
example. If you're talking about more advanced topics, then you can use a more
advanced example. In fact, you can use different examples suited to different
topics! Relax, there's no need to be a pedant.

~~~
Goladus
Honestly, when I was a newbie, the simplistic examples drove me crazy because
I didn't get the point. I can solve the toy problem effectively with concepts
already introduced (functions) why am I burdening my code and my brain with
all this new overhead?

The OP's suggestion to use a GUI interface is much better. GUI objects like
windows are a common and interesting subject. Ironically, Object Oriented
features in languages like Java and C# made a lot more sense to me after
writing a Win32 gui app in straight C.

------
CodeMage
The problem people have with "Car extends Vehicle" is that they expect magic.
It's the same impatience we sometimes feel with little kids because they're
not grasping something we've been taking for granted for decades. If you're
trying to teach someone _new_ to OOP, there is _no_ example that will take
them from their current level of knowledge to yours, in one fell swoop. You
can't expect them to grapple with decisions such as "inheritance vs.
delegation" when they're only now learning what inheritance is all about.

So yeah, "Car extends Vehicle" and "Duck extends Bird" works pretty well at
that point. You can try to cram "Penguin" and "Helicopter" and "Flyer" and
"Vehicle" down your students' throats in the same lesson, but I doubt that
will magically make them digest it properly. And if you can't do that with
easy stuff like "Duck" and "Bird", how do you expect them to swallow
"NumericHalo" and "ImageDisplay"?

------
bendmorris
This is ridiculous. I'm teaching part of a course called "programming for
biologists" this fall including the part about object oriented programming.
Most of my students are ecology grad students. You're telling me I shouldn't
use simple animal examples, when these are exactly the types of things my
students are going to be modeling?

------
cema
1\. I absolutely agree with the linked article. My perspective is somewhat
different, however. I submit that OO hierarchy should not mimic whatever
properties whatever _real-world objects_ may happen to possess. Instead, when
we solve a problem and have come up with a solution, the OO hierarchy should
describe the solution. A different solution, or a different problem, may
easily lead to a different hierarchy of (perhaps different) objects. And these
would be _software objects_.

2\. Therefore, I suggest that a "simple" example would come from a well-known
software system. Such as a window system (rectangle, button, icon, window,
etc) which, either as a concrete example or an abstraction, should be easily
understood by anyone with a minimal (desktop) computer experience and no
programming experience.

------
siglesias
I completely agree with this. Duck-laden object oriented programming tutorials
made no sense as I tried to transition from C to Objective-C.

The best explanation I found was Chapter 2 of Apple's "Object-Oriented
Programming with Objective-C":

 _Every object has both state (data) and behavior (operations on data). In
that, they’re not much different from ordinary physical objects. It’s easy to
see how a mechanical device, such as a pocket watch or a piano, embodies both
state and behavior._

[http://developer.apple.com/library/mac/documentation/cocoa/c...](http://developer.apple.com/library/mac/documentation/cocoa/conceptual/OOP_ObjC/OOP_ObjC.pdf)

------
kenjackson
I actually think these are really good examples. I especially like the shape
example, because you quickly run into problems where you can talk about the
difference between modeling for a solution and representing an abstraction.

------
guelo
I fail to see the problem. I would bet that there are tons of real games that
actually have a Car class that extends Vehicle.

------
yason
The thing is that there ought to be no trivial examples of object oriented
paradigms because they are never trivial.

If you're good you can create object oriented interrelations that work but end
up having object charts which have that plastic, phoney kind of artificiality
that makes little natural sense. If you're a god-like programmer you can come
up with interrelations of code and data that make perfect sense but they're
quite not always object oriented.

As for OO, the best thing I've settled with is this:

\- Scoop up all your programming experience and first think how do you want to
reuse some code or some data structures

\- Then you go and look up appropriate paradigms and language features that
_could_ support your case of reuse

\- And finally you go figure out how to best do it in a natural way in your
programming language.

However, I often start with basic lists and dicts and only after something
becomes truly obvious and a near-universal trait, I might make a class out of
it if I can better reuse code that way. An archetypical example would be
something like a BaseObject that supports some protocol for init, deinit, and
refcounting, for example. Everything else can adhere to that protocol. Better
yet, I'll make it an interface so I can decouple the implementation of the
protocol from the definition of the protocol.

------
Emore
Yes, a thousand times yes. I have never understood why dependency injection is
not taught in OOP courses -- as described in the article, DI truly shows why
OOP design is useful. Conversely, the "domain model"-approach commonly used
probably gains some of its attraction due to the similarities to E/R database
diagrams, but far from always lead to designs which are actually useful in
practice.

------
Kevin_Marks
Is Kragen making an elaborate joke about duck typing here?

Penguins don’t implement the “fly” method that can be found in birds. And you
don’t go around causing things to fly without knowing what kind of bird they
are. (Ducks themselves decide when they want to fly, and they certainly seem
to know they’re ducks and not vultures.)

~~~
kragen
> Is Kragen making an elaborate joke about duck typing here?

Not really, no. I was just saying that "fly" methods on hypothetical bird
classes fail to motivate OO.

------
joe_the_user
Just one piece in the whole _object orientation blows but still is the best
thing we have to make complex systems understandable to simple people_
quandary.

It is true that the real world object examples confuse everything that OO is
really used for. It is also true that we need them to make OO approachable at
all.

OO is essentially an ontological cluster-f _ck where multitudes of logical and
representational levels are trampled on. The thing is, OO_ uses* the adhoc
mixture of logical confusions that is most people's description of their
world. Somehow people's amazing brains muddle through speaking natural
language despite it's terrible muddling of everything. Thus we can stand the
confusion of not really knowing whether "class window" is a glowy thing on the
screen, a location in memory or an abstract datatype.

------
BenoitEssiambre
I would also add. Don't introduce a language by showing how to compute the
Fibonacci sequence.

I never have and never will need to compute the Fibonacci sequence. Recursion
is such an infrequent part of everyday programming that it doesn't really
matter if a language makes it easier.

~~~
TeMPOraL
It is frequent in some applications, and when programming in languages that
encourage you to recur instead of looping (see: functional proramming). Also,
recursion is one of the most important concepts of computer science.

I didn't really use recursion in my programming until I switched from C++ to
Common Lisp.

------
quanticle
>One disadvantage is that it has to deal with a fair amount of arithmetic;
there's lots of `/ float(n)` and `* self.rect.w + 0.5` and `self.size __2/2 *
(1 - (1 - age _2)_ *2)` and the like, which I think reinforce a common
misconception about computer programming: that you need to learn algebra and
arithmetic in order to write programs, and that programs mostly deal with
numbers.

Is this really such a disadvantage? Algebra and arithmetic are hardly advanced
subjects. Isn't it fair to insist that programmers know at least middle school
math before they program?

~~~
kragen
> Isn't it fair to insist that programmers know at least middle school math
> before they program?

Certainly not! I started programming when I was 4, many years before I got to
middle-school math. And there's a great deal of software in the world that has
very little to do with algebra or arithmetic. It's easy to open up
[http://www.canonical.org/~kragen/sw/urscheme/compiler.scm.ht...](http://www.canonical.org/~kragen/sw/urscheme/compiler.scm.html),
for example, to a random page and see no arithmetic at all. The same would be
true of [https://github.com/evilstreak/markdown-
js/blob/master/lib/ma...](https://github.com/evilstreak/markdown-
js/blob/master/lib/markdown.js) if JS didn't require you to use arithmetic to
iterate over arrays.

------
buster
I don't get what is soo wrong about the car example, because of it i grasped
the object orientation style instantly. What's easier to undderstand than
this!?

------
JulianMorrison
Inheritance. Gah, why won't this bad idea die!

Shared calling protocol, shared data sub-structures, fixed compile-time
equivalence hierarchy, all clumped together.

Go gets it right. Cut the linkage between composition and equivalence.
Composition handles inclusion/merging of existing objects. Interfaces handle
equivalence of objects. Interfaces can have hierarchies, but there's no one
true hierarchy baked into the objects they describe.

------
bjoernbu
The example for inheritence I liked best was something like this:

Number (implementing trivial exponentiation through multiplication)

RealNumber & ComplexNumber implementing their specific kind of multiplication.

Later on replace the exponentiation by fast exponentiation. This directly
demonstrates the benefits of avoiding code duplication.The change only has to
be made in one place.

------
pacmon
The real truth being that not even one thinks the same way. Some people learn
better with visuals versus some who prefer text.

Some people see no problem with Vehicle->Car or Animal->Duck or whatever other
ultra basic OO example.

In the end what's best is whatever can make someone understand the concept.

------
wlievens
In my experience, there's a process where adding accuracy (and thus usually
complexity) to a domain model, implies removing existing inheritance
assumptions.

For instance, in the trivial case an Employee is a Person, but when you go
further you discover that there are all sorts of relations that need more
detailed fleshing out. Is changing jobs just a call to Employee.setEmployer?
That certainly feels akward. And as that process continues, you get a more
complex domain model with comparatively less fixed inheritance relations.

The extends keyword sortof becomes an extend object, first-class among your
domain and susceptible to dynamic behaviour.

But can you teach kids that in a first OO class?

EDIT: care to explain the downvote? I'm quite passionate about this subject so
would love to debate it.

------
aufreak3
Good to remember Alan Kay's guideline here - "OOP to me means only messaging,
local retention and protection and hiding of state-process, and extreme late-
binding of all things."

------
dtreacy
THAT'S WHY ITS A BEGINNER TUTORIAL. Get off your high horse.

~~~
lyudmil
The criticism being put forward isn't at all arrogant. A tutorial for
beginners that teaches you the wrong thing is incredibly detrimental. It's
good to point that out and fix it.

~~~
dtreacy
"Duck extends Bird" is not the wrong thing at all. As other comments have
pointed out, the justifications in the article don't apply to someone who is
just starting out learning the basics of OO.

------
therandomguy
"Car extends Vehicle" is a perfectly fine example to introduce someone to OO
programming. That's all.

------
georgieporgie
If I understand correctly, this rant is about the use of simplistic examples
in teaching OOP, correct? i.e. it's not just about using such examples when
debating language features.

If so, then I very strongly disagree with this guy. I have painful memories of
trying to come to grip with OO in high school in the early 90's. Sure, those
zoological and automotive examples are almost insultingly trivial, but that's
because you don't need real-world engineering complexity interfering when
you're just trying to wrap your head around inheritance and extension!

Bird ==> Duck makes sense because they're classes. As in, those are classes of
animals in the real world, and there is a relationship among them. Expressing
that relationship in code doesn't mean you're coding animals, it means you're
modeling a real-world class hierarchy with your data definition.

I think that people are forgetting that OOP is actually _hard_. If you don't
already have a very strong grasp on the underlying mechanics of a language
(e.g. function pointers and vtables in C++), then it's going to always seem
like magic.

~~~
kragen
I appreciate your disagreement, and I might be wrong. My concern with those
examples is not that they're _trivial_ but that they're _misleading_.

------
sabat
Nothing annoys me more than this kind of analogy. People who are trying to
understand it can't figure out what a Duck really is in this scenario, and
what it means that it's a subclass of Bird.

Use simple but realistic classes as examples.

