Live data from Hacker News

Goodbye, shitty "Car extends Vehicle" object-orientation tutorial

lists.canonical.org

111–120 of 134 posts

Re: Goodbye, shitty "Car extends Vehicle" object-orientation tutorial

#111
post #95

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

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.

Re: Goodbye, shitty "Car extends Vehicle" object-orientation tutorial

#113
post #91
post #42

Earlier quoted context omitted.

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…

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.

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.

Re: Goodbye, shitty "Car extends Vehicle" object-orientation tutorial

#114
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.

Re: Goodbye, shitty "Car extends Vehicle" object-orientation tutorial

#115
post #6

> 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 propo…

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…

Actually, this makes more sense as a trait or interface than as a superclass, especially as you're not even implementing any behavior.

It's the same way for squares and rectangles. Square does the Rectangle and Quadrilateral interface, Rectangle does the Rectangle and Quadrilateral interfaces, and it doesn't matter. If you want a subtype/supertype relationship, then you have to diverge from what people intuitively think about classes. Liskov's Substitution Principle says that subtypes must be completely substitutable anywhere a supertype is used, which means a rectangle isa square because a square does setX, getX, and getY, whereas a rectangle does setX, setY, getX, and getY. (This doesn't make much sense because people use inheritance as "copy and paste this crap from the superclass into my subclass" rather than to setup substitutable subtype/supertype relationships.)

Interfaces avoid that problem because there is no supertype or subtype, only equal types that agree to have the same interfaces. Then it doesn't matter if a square isa rectangle or not.

Re: Goodbye, shitty "Car extends Vehicle" object-orientation tutorial

#116
post #94

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.…

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!

Re: Goodbye, shitty "Car extends Vehicle" object-orientation tutorial

#117
post #7

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…

I agree that the proposed replacement is terrible.

I'd suggest files are a great example for people who have a programming background because you can quickly show problems (e.g. streams considered as a subclass of files) that entail the kinds of tradeoffs and decisions the author rightly points out are shortcomings of the duck example (most of the shortcomings listed are in fact more a case of the author trying to show off and not problems with the example at all).

But, you know what, duck, bird, and penguin are actually just fine. As the author himself (I assume it's a him) points out, penguins can't fly. And let's say that over hear we're doing vehicle, car, plane, and helicopter. How can we avoid implementing flying twice? And is it a good idea to treat flying like a plane, a helicopter, and a bird (but not a penguin) as the same thing. Oh, and the way penguins swim is amazingly analogous to flying, how can we leverage that?

So, bye bye shitty drum machine example. I'm going back to duck and bird.

Re: Goodbye, shitty "Car extends Vehicle" object-orientation tutorial

#118
post #55

Earlier quoted context omitted.

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. L…

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

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

Re: Goodbye, shitty "Car extends Vehicle" object-orientation tutorial

#119
post #10
post #6

Earlier quoted context omitted.

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…

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 affe…

The 'CEO singleton' - very funny. :)

However, I'm all for domain modeling in the beginning, for a beginner. I learned OO the hard way - all by myself and pouring over books. I agree with the OP that a vehicle or duck was not a good model. Having worked with databases and crm's in the past (before they were 'crm's), I always dealt with people, organizations, calls, notes, etc. So when I came across an infamous car example, I was always wondering 'this has no bearing on anything I would do - why not talk about real objects like people?'.

Even before hitting any kind of patterns, it's crucial (in my mind) to understand datatypes, methods, scoping, inheritance, etc. 3 Simple classes like Person, Address, Organization can go a long way.

In my mind, there's no way a beginner is going to understand patterns first. They have to be shown the basics and the have to be handheld when entering the OO way of thinking. One those first few steps are taken, then it paves the way for more complex examples and patterns.

Re: Goodbye, shitty "Car extends Vehicle" object-orientation tutorial

#120
post #9

Earlier quoted context omitted.

Is "Spaceship extends GameObject" really that different than "Duck extends Animal"?

When people say "Duck extends Animal" is bad they typically mean that it's trying to model real-world relationships rather than computational relationships. The example is meant to demonstrate that inheritance should be based on what inheritance means for your program, to make your codebase "nicer", and not to simply categorise your objects. "Spaceship extends GameObject" exists mostly to facilitate polymorphism and…

"It's implied that the relationship was used because real ducks are real animals, not because Duck inheriting from Animal is a good idea."

I just do not understand this objection. If you wrote Sim Farm, it's quite possible you'd want Duck to inherit from Bird and Cow and Pig to inherit from Mammal, and both Bird and Mammal to inherit from Animal.

In the course of caring for your farm, you have to fix tractors, grow crops, and care for animals.

All Animals must be fed and will starve if they don't. Why would you code "needs food" on every individual animal class? Birds can get avian flu, and Mammals can get rabies; the pigs can even get rabies from the dogs. Why would you code "can get rabies" on Dog and Pig?

Maybe you don't always want to use Sim Farm as your example for teaching OO, but a lot of working code does model real-world items. Animals and cars and such are no worse than files as objects to model, and have the advantage that non-programmers already know something about them. Hence they can focus on the OO concepts and not on the domain logic.

Post reply on HN