10 ms·
> 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 h
by jeffreymcmanus 15y ago
> 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.
- scott_s 15y agoI agree, but he gets to a much simpler, teachable example near the end, which is representing shapes. Mathematically, a circle is an ellipse, and an ellipse is a polygon. It's much cleaner than the biology or work-place inspired taxonomy. A simple drawing program can feel less contrived, but, then again, so can simple games that use an object hierarchy unrelated to polygons. Fundamentally, though, I do agree with your point. You don't use completely realistic examples to teach concepts for the fist time. All of the incidental material that is necessary to grok the example clouds the new concepts. Sometimes this means the examples will be pedagogical toys, and that's okay. The benefit of the already known taxonomies is that the student has less to learn. The new concept is more obvious. If the worry is that the example is too much like a toy, then address that in the second example. In general, I think people put too much emphasis on first exposure to concepts. Education is iteration. If it doesn't take the first time, there are more tries coming up.
- georgefox 15y ago> I agree, but he gets to a much simpler, teachable example near the end, which is representing shapes. Mathematically, a circle is an ellipse, and an ellipse is a polygon. Well, the circle-ellipse problem complicates that example a little bit: http://en.wikipedia.org/wiki/Circle-ellipse_problem http://en.wikipedia.org/wiki/Circle-ellipse_problem.
- kragen 15y agoThe circle-ellipse problem almost never arises in real software, in my experience. It's not in the same league as the Fragile Base Class problem, or the Diamond Inheritance Problem, or the Schema Upgrade Problem, or the Ravioli Code Problem, or the problem of poor performance caused by too many layers of abstraction, or the Big Ball Of Mud Anti-Pattern. It's essentially a thought experiment. What does it teach us? Well, one lesson is that you can't design good inheritance hierarchies in your program simply by aping ontological relationships in a Platonic Ideal World, which is the main point of my article. Another lesson is that sometimes you'll discover that your program is inadvertently violating LSP because of some nonobvious interaction, and that this is a bug, and you need to fix it. A third lesson is that mutability is tricky, in particular with respect to the Liskov subtyping relation; this same problem comes up in non-OO contexts as well, if you have mutability and any kind of subtyping relation. (OCaml polymorphic variants, for example, create a subtyping relation all by themselves, even without OCaml's OO features, and that's enough to create the problem.)
- mattdeboard 15y agoI agree without caveats. "Car extends vehicle" and "duck extends bird" are great examples for the type of lesson they're trying to teach. I'm surprised people have time in their lives to worry about this crap. edit: Also, what's up with the title for this submission?
- haberman 15y agoIf it teaches people to think of object-oriented programming as world-modeling, it is not a great lesson. Polymorphism is an abstraction technique whose goal is substitutability. "Car extends Vehicle" is useful if other kinds of Vehicles can be substituted for cars. If you teach someone that there is value in making Car extend Vehicle just because that expresses a real-world relationship, you are teaching exactly the wrong lesson and your students will create overly complex inheritance hierarchies.
- hugh3 15y agoPolymorphism is an abstraction technique whose goal is substitutability. "Car extends Vehicle" is useful if other kinds of Vehicles can be substituted for cars. "That's great", thinks the student, "I'll keep that in mind on the offchance I ever need to write code for an automatic carwash..." Honestly I think these examples are fine as far as they go, but they should be immediately followed up with nontrivial examples demonstrating how you might actually use this in programming problems which don't fall into the category "simulation of real-world objects". Otherwise the student can easily dismiss the whole idea as esoteric.
- mattdeboard 15y agoYes, you're right, it's only a great lesson if it's taught properly. I mean, really? Doesn't that seem like hair-splitting to you? In my opinion, dickering about this is the equivalent of, "Yeah, those two hortizontal parallel lines are a great symbol for equality as far as it goes, but really students need to understand the difference between equivalence and implication!" It's an equals sign. Same deal here. It's an analogy. The fact that analogies must be taught properly to be useful is a tautology that doesn't even bear mentioning, yet here we are.
- haberman 15y agoYou 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.
- marshray 15y agoIs "Spaceship extends GameObject" really that different than "Duck extends Animal"?
- haberman 15y agoYes, because drawing a bunch of game objects on a screen is something a real program might actually want to do, and therefore opens up opportunities to talk about real-world design tradeoffs. Making a program print "quack" when you call the "speak()" method is something that only happens in textbooks, and since there's no reason to actually do that there's no easy way to discuss the alternatives and why polymorphism is a win.
- fleitz 15y agoSo what you're saying is that Farmville is the ultimate result of reading OO textbooks, and that if they had spent more time on a realistic model such as spaceships and gameobjects that a game such as Knights of the Old Republic could be produced by Zynga?
- wlievens 15y agoThat has nothing to do with what haberman is saying. Most people know games, and a simple game model can be expressed in inheritance terms in such a way that's illustrative and less contrived than conventional tutorial metaphors. And I agree with that.
- jerf 15y agoHis point is that you can't add code to ducks... full stop. If you want to talk about "software [that] tracks ducks", then do so, but by talking about physical ducks one further encourages the ancient fallacy that object orientation is about physical modeling and should be all about physical objects and their physical relationships. What was said was what was meant; you can not add code to ducks. They shouldn't be in the tutorial at all, just as Chevrolets shouldn't be.
- marshray 15y agoA lot of OO was, in fact, influenced by the task of writing programs for simulations. It's conceivable someone might actually want to develop animal/bird/duck classes (e.g., SimAnimals). http://en.wikipedia.org/wiki/Simula http://en.wikipedia.org/wiki/Simula
- jerf 15y agoYes, I know. That's where the idea came from. Nevertheless, it's a terrible introduction to OO. It promotes very wrong conceptualizations and horrible code. And odds are, even if that is the type of code you're writing, you still shouldn't be trying to have a one-to-one mapping between physical things and classes and/or instances. It just isn't a very good way to work. Just because it was the first thing that was done with OO doesn't mean that it was actually a good idea. (Actually, the whole idea that the first person to implement a technology or methodology is forever the one and only true authority the one and only true definition is a bizarre one anyhow; of all the people who implement a particular methodology, isn't a bit much to expect the very first person to get every detail correct? You can see this in a lot of purist debates in our discipline.)
- bryansum 15y agoSimula67, the version most identify as Simula proper, actually evolved concurrently with Smalltalk. Rick DeNatale's memoir has a great article debunking some early OO myths -- http://talklikeaduck.denhaven2.com/2006/07/29/about-me http://talklikeaduck.denhaven2.com/2006/07/29/about-me
- hugh3 15y agoPersonally I'd add the code to "TrackedObject" rather than "Duck" just in case we ever wanted to track geese or cormorants. 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. Perhaps, though I think his real point is that often folks teaching software development will only put out that first hurdle and forget about the rest. Teach 'em that "ducks are animals" and think they understand inheritance, when in fact these simple physical analogies are a bad way of understanding how and why you might use inheritance in the real world. I think it's a phenomenon quite common across the whole OO pedagogy, in fact. If your only mental examples of "objects" are ducks and bicycles then you're going to get pretty confused when you escape simple example land and start trying to understand the difference between an NSView and an NSViewController.
- MatthewPhillips 15y agoTrue, but I still don't think this is a good analogy. When you are learning inheritance you don't know what "x extends y" even means. Using a non-code example obscures what you are talking about. I'd use an example like this: HPDriver extends PrinterDriver. CanonDriver extends PrinterDriver. EpsonDriver extends PrinterDriver. See, you can make 3 different drivers and share common printer code. That makes sense to me if I'm just learning inheritance. Duck extends animal does not.
- barrkel 15y agoI'd object to your example: your example seems to me to be closer to that of instance :: class than subclass :: superclass. PrinterDriver defines a contract; each of HPDriver, CanonDriver etc. will need to fulfill the contract. But I don't see them usefully adding behaviour. The OS would have to already know about HPDriver in order to use its extra functionality - then what's the point in using inheritance at all?
- seabee 15y agoIn a lot of OO languages instances rarely have different behaviour to each other. You are also forgetting that it's possible to have more than one printer using the same driver (i.e. multiple instances of a class of printers). This is not uncommon when you consider network printers. > The OS would have to already know about HPDriver in order to use its extra functionality And that isn't true of any other instance in which inheritance is used?
- sjs 15y agoA common pattern is a superclass with "abstract" methods that subclasses then implement. So the `sendCommand(cmd)` function is implemented in HPDriver and CanonDriver and higher level methods in PrinterDriver can use that piece even though PrinterDriver itself has no implementation of that method.
- sethg 15y agoDifferent printer models could have different features (color/B&W, selecting output tray, “print” an outgoing fax, etc.), and you could make each PrinterDriver subclass responsible for generating the appropriate UI code for frobbing those features.