17
$\begingroup$

What is the most effective analogy that you have used or have thought of to teach the object oriented paradigm? Hopefully the analogy can translate well to inheritance as well, and includes the concepts of instance methods, class methods and properties. Even better would be if it also includes the concept of singleton classes.

A similar question exists on Stack Overflow. I would like to duplicate it here because on Stack Overflow it was closed an "Not Constructive."

It also exists on Software Engineering, where is not closed but it has historical lock. This means that "it is not considered a good, on-topic question for this site." Again, it should be re-asked here.

$\endgroup$
  • 3
    $\begingroup$ I'm voting to close as too broad, because there's no such thing as “the” object oriented paradigm. A lot of concepts hide behind these words, they're different concepts depending on who's talking and what language they treat as the one true way of doing things, and different analogies will be needed for these different concepts. $\endgroup$ – Gilles May 27 '17 at 23:44
  • $\begingroup$ It is broad, but I wouldn't say it's too broad. Just because there is no "correct" answer doesn't mean that it's too broad. There are many different ways to kill a process, each with upsides and downsides, but they all could be covered by one question. $\endgroup$ – thesecretmaster May 27 '17 at 23:51
  • 1
    $\begingroup$ You're cherry-picking different aspects of different flavours of OOP. They are not official. You have selectively ignored some core aspects. This question is poor: OOP is not something to be taught by a simple analogy. In my experience, teachers who use analogies for OOP cause massive damage to their students' learning. Teach OOP, don't dumb it down. $\endgroup$ – user31 May 28 '17 at 18:37
  • 1
    $\begingroup$ @Adam I agree in principle, but a good analogy, if there was one, would be helpful. Didn't Robert M. Prisig say that everything is an analogy? Poor analogies cause damage, like poor anything. We can't rebuke the only tool that we have for teaching abstract ideas (comparing them to something concrete). Consider Piaget with the Concrete and Formal Operations stages. What experience do the students have, how old are they, what are the trying to learn? I have been reading a book about anthropology that says that the Apprenticeship model is basically the first way of teaching (pre-language). $\endgroup$ – user737 Jun 15 '17 at 14:51
  • 1
    $\begingroup$ In the essence, OOP is based on messages and contracts, an object pass a message to another, which will eventualy return a value, whatever it does within in process is unkwown by the sender of the message. Otherwise a good way to restrict the scope of your question would be to limit yourself to encapsulation, polymorphism and inheritance. Which is the basis of OOP. Patterns (singleton) that come as specific usage of those bases is a somewhat another subject that come after. $\endgroup$ – Walfrat Jun 28 '17 at 11:02

16 Answers 16

10
$\begingroup$

I've got to jump in here and talk about my experience having to help a former boss understand why the project he wanted to do wasn't possible in the time available. It came down to incompatible data types and he just couldn't see why I couldn't convert from one to the other (he wanted to do real-time motion capture using an XBox Kinect to animate a 3D mesh of the circulatory system and thought this was easy).

Ben I.'s answer touches on this too, but I can add to it. He says this:

The objects keeps track of some kind of information (instance variables), can be interacted with only in specified ways (interface), have setters (switch/button) and a getters (lights, your eyes).

There's more to it than that. In this electrical engineering paradigm (which should be familiar to most), a light switch that has two states is the most basic example.

  • It has output: bool isOn()
  • It has a method of supplying input: toggle()
  • Underneath it has an implementation of what toggle() does and how that affects the return value of isOn()

Buttons can also be described in this manner:

  • It has output: bool isOn()
  • It has a method of supplying input: push()
  • Underneath it has an implementation which differs from Switch slightly: after push() is called the output is true for a short duration, then automatically returns to false. That is, the user must continue to interact with the button in order for the output to be true.

A knob also has similar features, although different types are involved:

  • It has output: float getValue()
  • It has input: twistTo(float v)
  • Underneath it has an implementation

But here's where it gets interesting:

What happens if we define an object that implements both Knob and Button? We should expect the following description:

  • It has output: float getValue(),bool isOn()
  • It has input: twistTo(float v)
  • Underneath it has an implementation
  • After input is supplied, isOn() becomes true, then after a duration becomes false again. In order to keep isOn() returning true forever, we must continue interacting with the object.

What do we end up with?

A timer switch

We can twist it to set the value, which turns the output on and displays the value. Then after a duration defined by that value it turns itself off again. As the homeowner we don't care how it was implemented only that they can interact with it in a certain way (defined by those interfaces) to get the desired behavior.

And yes, I'd present that to students in that manner. Describe the simple items (button, toggle, knob, timer) and then ask the students to figure out what happens when two of them are combined. The epiphany moment when it clicks will do wonders. That's the difference between being told and being taught.

You can expand on this analogy quite far, as well: Three-way switches, time-locks, missile launch confirmation (you need to press two buttons at the same time), sliders, gauges...

And then...you can get to events. Instead of treating the wires in the analogy as hard links in code (while(switch.isOn()) { ... }), you can treat them as events: when the switch changes state, that update propagates to all objects listening for it and they handle the state change as their implementation dictates (switch.addListener(this.doWhenToggled)).

The classic "cats are felines, felines are mammals, mammals are animals" hierarchy only gets you so far and provides a very poor and rigid understanding of Object Oriented Programming that causes new programmers to tend towards Do-Everything Objects (where do float planes fit in the "boat extend vehicle, plane extends vehicle" hierarchy? Clearly the only solution is to make all vehicles drive, fly, and float and just disable the ones we don't need!) rather than through a composition of interfaces (say, FloatPlane extends BaseAircraft implements IWaterCraft).

I know that sort of thinking messed me up for a number of years. Heck, I'm still recovering from it: I still can't read inline lambda expressions natively, I have to decompose them, and it often takes me several minutes. Same thing goes for creating interfaces, I often have to go the "cats are felines" road until I hit a spot where I realize "I want to use this code on both cats AND cars" because they both share some property that doesn't exist in the common class (and shouldn't) and I have to refactor.

Of course, refactoring is a good thing. Give your students a powerful IDE and teach them how to use the refactoring tools. Eclipse is the god of these , offering an astounding fourteen different options, including "Extract Interface" and "Use base type where possible." Even if they make a mistake, now they know how to fix it in moments rather than hours. No one wants to (and no one will) spend hours fixing an inheritance problem that can be solved by a quick copy and paste; "code duplication, meh, never hurt me."

$\endgroup$
  • 1
    $\begingroup$ Welcome to CSE! This is a gorgeous answer, and I hope we hear more from you in the future! $\endgroup$ – Ben I. Jun 22 '17 at 18:44
  • $\begingroup$ @BenI. I saw another question on the Hot Network Questions the other day but this one pulled me out of the woodwork. I will probably be more of a lurker, though! $\endgroup$ – Draco18s Jun 22 '17 at 18:52
  • $\begingroup$ More's the pity. Pipe in whenever you get inspired ;-) $\endgroup$ – Ben I. Jun 22 '17 at 18:57
  • 2
    $\begingroup$ Your third-and-second-to-last paragraphs are really important. The "zoo" type introductions to OO are, in my opinion, extremely destructive. They can mess up how people think about OO design in a subtle way for a really long time. Switches, lights, and anything where there's a natural input, output and desired behavior are so much better than "a cat is an animal, so Cat.MakeNoise() should return 'meow'". $\endgroup$ – Ben Aaronson Jun 29 '17 at 17:23
  • 2
    $\begingroup$ This can also lead on really nicely to encapsulation and abstraction as concepts. Note that the wiring from a switch to a lightbulb isn't accessible to the user. And that not knowing whether a class member should be public or private is like not knowing whether part of a TV should be on the inside or outside! $\endgroup$ – Ben Aaronson Jun 29 '17 at 17:23
7
$\begingroup$

A good analogy might use animals and their classification.

Class: think felines. A feline will purr, go out only at night, eat meat, etc. One could think of the methods purr, goOut:time, eat:food, where a valid feline will only accept a night time and food that is meat.

Inheritance: meanwhile, felines are very different from each other, despite sharing much of the same physiology (implementation). They observe many similar behavior (interface), but different types of cats have different behavior ultimately. A domestic cat's purr will be very different from a tiger's. Meanwhile, a tiger will be able to predate on another animal (think the method predate:), but a cat will not.

Instance: specific cats. My neighbor's kitten, the tiger in the city zoo, a lion somewhere in Africa, etc.

$\endgroup$
  • 2
    $\begingroup$ Poor. How is inheritance here? A domestic cat is not a tiger, and a tiger is not a domestic cat. I see here many sources of easy confusion between class vs object, instance vs instance, and every combination. $\endgroup$ – user31 May 28 '17 at 18:40
  • $\begingroup$ A domestic cat is a feline and a tiger is a feline. I apologize for using cat and feline interchangeably here. $\endgroup$ – xuq01 May 28 '17 at 18:41
  • 2
    $\begingroup$ But this is still muddling up classes and objects for the students. I'm reading this as: feline as an abstract class (there's no such physical thing as a "feline"), tiger/house-cat as objects. But also classes. But objects. What's the difference? ... and the pain begins (I've seen many, many, many students go down this route. I don't believe we should use analogies in OOP teaching). $\endgroup$ – user31 May 28 '17 at 18:45
  • $\begingroup$ And then you are throwing away languages which forbid multiple inheritance $\endgroup$ – Sarge Borsch Jun 19 '17 at 12:43
5
$\begingroup$

I mean, one very clear analogy for Objects is, well, objects. But these are special sorts of objects. You might show some videos like this one to make it clear:

The objects keeps track of some kind of information (instance variables), can be interacted with only in specified ways (interface), have setters (switch/button) and a getters (lights, your eyes).

So, we are talking about objects that have the ability to do things, have interfaces by which you can get them to do them, and don't show you how they work inside.

Then you have a nice segue into constructing an Object together.

What nice about using objects as an analogy for Objects is that, well, that's what they were named after, so that's really the philosophical conception from the start.

$\endgroup$
  • $\begingroup$ The two best objects to use are "vehicles" and "computers." The benefit to both is that they, commonly, have inner workings (private methods and data) that are not exposed by the interface. The "vehicle" class can start with a bicycle (no motor) and move on to cars/trucks, and just in case "wheels" gets thought of as a base class attribute, what about the helicopter? The benefit of the computer as a sample object is that it should already be in the classroom and easily compared to the smart phone and tablets that students are likely to have available as well. $\endgroup$ – Gypsy Spellweaver May 25 '17 at 3:00
  • $\begingroup$ I teach OO because it is used, but I also have a bookmark to: "Object Oriented Programming is an expensive disaster which must end". I assume you do. $\endgroup$ – user737 Jun 15 '17 at 14:58
5
$\begingroup$

I have thought of different sizes, shapes and colors of boxes.

This would work better for younger students, and would work better if you use the box analogy for variables.

Basically, all boxes are boxes. Some are square and some are round. There are white square boxes and brown square boxes, but they are both square boxes and can both fit similar things. Another example: A filing cabinet or cupboard is basically a box that can hold other boxes (a collection). You can of course use other examples too.

Requested examples:

Inheritance: A regular box and a cooler can hold the same types of items and are about the same size, but a cooler, in addition to storing things, keeps them cold.

Instances: Get two of the same type of box. Put an object (like a rubber duck) in one, and a similar one (maybe a different rubber duck) in the other. They are separate instances of the same class.

Properties: From the previous example, the duck in one is yellow and looks like a wizard, and the other one is orange and looks like a tiger.

More examples tomorrow, I'm going to bed.

$\endgroup$
  • 1
    $\begingroup$ I use a similar analogy for variables. Could you elaborate a bit on how you might use boxes to model inheritance, instance methods, class methods, and properties? I think there's more here that could be expanded upon. $\endgroup$ – Peter May 24 '17 at 23:50
  • 1
    $\begingroup$ @OldBunny2800: There's no need to include 'EDIT:' in your post—see What's wrong with putting “EDIT: …” in the body of a post?. Users can check the revision history to see when you edited, so you needn't clutter your post with EDIT: if you don't want. $\endgroup$ – Aurora0001 May 26 '17 at 15:43
4
$\begingroup$

A good analogy you can use is a human analogy. Everybody is a human, but each of them has a different characteristic. Different eye color, hair color, skin, etc...

Anybody can easily relate to this cause we are all human.

$\endgroup$
  • 1
    $\begingroup$ I use this one too. It goes Thing > Living Thing > Animal > Mammal > Human > Student > High School Student > Computer Science Student > 3rd Period Computer Science Student. We add in properties and methods at each level when we talk about inheritance. $\endgroup$ – Ryan Nutt May 25 '17 at 15:04
4
$\begingroup$
Wheeled vehicles
 |-human-propelled
 ||- unicycle
 ||- bicycle
 ||- tricycle
 |-animal-propelled
 ||- cart
 ||- carriage
 ||- ...
 |- motor-propelled
 ||- motorcycle
 ||- car
 ||- ...

This allows you to explore both subclassing and composition.

$\endgroup$
  • 1
    $\begingroup$ Then you could say, "Oh, new requirement: handle non-wheeled vehicles as well." This would let them consider the aspects of the structure that can be built on, modified, extended... vs those that cannot. A good implementation vs poor one. $\endgroup$ – user737 Jun 15 '17 at 14:55
4
$\begingroup$

I'd turn the lesson on its head. Say, I am writing a game and I need to track what's going on. To start my game is going to feature a "good guy" running around fighting "bad guys". So I write Good guy and Bad guy classes.

Unsurprisingly, these classes contain a lot of similar code. They both move, etc. so we can take that code and break it out into a common base class...

... and just keep extending the metaphor. Bad Guy's need AI, Good Guys need control input, etc.

$\endgroup$
3
$\begingroup$

I'm in the midst of a PennX course on edX called Software Development Fundamentals taught using Java, and they gave the analogy of parts of speech.

  • Objects -> Nouns
  • Methods -> Verbs (i.e. Actions)

I think you could expand it (without going too far with the metaphor) as follows:

  • Properties -> Adjectives
  • Class and (instance or subclass) -> Common noun and proper noun

This analogy is strengthened by the use of "is-a" and "has-a" in the context of OOP. The transition from natural language constructs to OOP (or vice versa) may aid in discussions of class design.

For example, a Car object could be a blue Honda Civic, the adjectives blue and Honda corresponding to properties set upon instantiation and the noun Civic either being the variable name of the instance or a subclass. Using natural language also helps with instanceof() as students will hopefully see relatively intuitively that a Civic is quite clearly a car, but a car is not necessarily a Civic.

$\endgroup$
2
$\begingroup$

A class is a small-program, an object is an instance of the small-program. A program is a collection of small-programs, that work together to achieve something bigger. A bit like Unix (bit different), where small-programs are connected with pipes. Objects are connected by messages, and you have to compile to link things together.

$\endgroup$
  • $\begingroup$ I think that this is the original vision for OO, which apparently got lost somewhere along the way. $\endgroup$ – user737 Jun 15 '17 at 15:01
  • 1
    $\begingroup$ @nocomprende Oh cool, it looks like I groked it. $\endgroup$ – ctrl-alt-delor Jul 22 '17 at 8:36
2
$\begingroup$

There are various analogies that work well, such as different kinds of vehicles. However I think you should quickly move towards discussing something that can actually be programmed. For example, you can discuss a system for tracking different types of employees. Game programming also fits the object-oriented paradigm well. You can first discuss the concepts of different types of game characters, and then go ahead and actually program it. (Perhaps initially students can use Greenfoot or a game maker program to create the game.)

$\endgroup$
2
$\begingroup$

I might be in minority here, but I hate using THINGS as analogy to classes. Classes are about abstracting behavior, and THINGS are not behavior.

So, in my opinion, best way to give people idea about OOP is to start with some complex behavior and show them how that behavior can be structured into classes.

Idea that immediately comes to mind is to start with some complex, procedural code and use refactoring to create class structure out of it. This will allow students to contrast and compare two possible ways how code can be structured.

Few things I would expect from this code. First I would expect there to be a complex method, with lots local variables and lots of code accessing those variables. This could then be refactored into class with local variables turned into fields and whole method split into smaller methods, each having access to the fields.

Next I would expect there to be some plain data structure, with code operating on this data structure. Maybe the above step would extract a method that works only with this data structure, and then that method could be moved into the data structure, making it a proper class. This could also work by introducing private fields, as the internals of the data structure might really be accessed by it's member method.

Next thing I would expect is some kind of switch that decided what calculation is used based on some kind of external parameter. This could be extracted first into individual class with method and then into class hierarchy with inheritance/interface, with concrete implementation passed in instead of "type" discriminator. To make it more complex, each of those calculations might want different input parameter, which might create complex method parameters, but would be simple if each concrete "calculation" class has it's own parameters.

In the end, this will show classes are just different way how to structure behavior and that there might be classes that don't have noun (or a thing) associated with them.

$\endgroup$
  • $\begingroup$ While this is certainly an interesting take on how to teach OO, it isn't an analogy and so doesn't exactly answer the question. I think that it brings value to the question anyways, so +1. $\endgroup$ – thesecretmaster Jun 22 '17 at 10:14
  • $\begingroup$ @thesecretmaster I do consider it an analogy. Just that the analogy is behavior. And how best to encode behavior than with code? $\endgroup$ – Euphoric Jun 22 '17 at 10:33
2
$\begingroup$

Lots of the answers here focus too much (imo) on inheritance. I find that I write better code when I think of OO as primarily supporting composition, not inheritance. In this view, a good analogy is an automobile. It is made up of many parts (objects) that interact in interesting ways to provide a functionality. You can substitute nearly any manufactured product, say a computer.

If you program this way you find that your hierarchies are very shallow and your classes are composed of many parts defined by other classes. It also minimizes the tendency to have class fields mostly primitives that are specifically manipulated by this class, instead having actions deferred to the other classes.

Thus, a gas pedal doesn't need to know anything about an engine, but both are parts of a whole. Likewise, recursively, the parts in the composition are themselves composed from simpler things. Eventually you get down to primitives (ints and strings) but hopefully not for a long time.

An added benefit of this world view is that you can, for the longest time, write the program using names associated with the problem space rather than the solution space. So a car has a GasPedal with a method press, rather than having an int that is just directly manipulated by the automobile object. I find naming according to the problem space, not the solution space also helps one communicate with users/product owners who, themselves, think in that space.

A consequence of this view, perhaps not obvious, is that the solution begins at the top level, adding classes for the parts as you find the need for them. This, as opposed to building lots of small "parts" classes speculatively hoping that they will fit. It also fits well with test first programming style.

$\endgroup$
2
$\begingroup$

One classic example (not original with me, used by many of my colleagues) comes from using modeling compounds (e.g. Play-Doh), and the many tools that come with them.

In short: you take raw memory (the Play-Doh), apply a class definition to it (one of the cutout forms), and you get an instance of an object (a Play-Doh shape). You can make multiple instances (multiple shapes) by re-using the class definition on new memory forms. Each instance can have different attributes (colors) but still belongs to the same class (collection of objects made from the same cutout).

$\endgroup$
  • 1
    $\begingroup$ Hello, and welcome to Computer Science Educators! Thanks for your answer; I hope to continue seeing you around the site. $\endgroup$ – heather Jul 22 '17 at 22:47
1
$\begingroup$

At the point in my CS1 class where we discuss OOP, my students are somewhat comfortable with the procedural paradigm. So, we first reflect on that before talking about OOP.

Procedural solutions: moving pieces of data around and manipulating them. I go back to a cooking analogy and compare programs to recipes: break eggs, add flour, beat those, add vanilla, etc. I say we think about programs in terms of basic ingredients (inputs), containers (variables), moving these around (control flow) and doing things to them (operations).

OOP: I draw heavily from Yegge's Kingdom of the Nouns to describe OOP, since I think it is both a good description and a hard criticism of OOP. The "Noun is King" and we design everything around that. Yegge has lots of good analogies directly in his description, but I don't employ all these at first. I do emphasize that we design everything around some "Big Nouns."

My primary working example of a "Big Noun" is a Whale, and I try to bring analogies back to this when possible.

  • The Whale class is a category of animal, whereas bruce = Whale() and sally = Whale() are both instances of Whale. The analogy is that instances are like individuals (the human-like names are very intentional).

    I also tap into a secondary analogy: a class is like a cookie cutter and the cookies are instances. Students find the idea of "stamping out" an instance by "using the class" to be fairly intuitive. Bonus: whale cookie cutters can keep the main analogy going.

  • Member functions are verbs (analogous to objects being Nouns): bruce.eat(fish) and sally.sing()

    Secondary analogy: methods are like little remora who are attached to the whale and do stuff for it, like sally.clean(). All verbs only exist if they are attached to some noun.

  • Data members are data that relate to the noun. The extension of the analogy is that they are adjectives that describe the whale: bruce.weight_in_tons = 200

    Secondary analogy: these are data inside the whale, like ambergris or Pinocchio. The data go into the whale, maybe its transformed or grows while inside the whale, maybe they get spit back out later, etc.

  • Inheritance: as others have suggested, the analogy is animal taxonomy. A BlueWhale is a Whale. All BlueWhale have a blowhole (like other wales) but they also have baleen, etc.

Its not a perfect analogy, but I get mileage out of it.

$\endgroup$
1
$\begingroup$

Another analogy which comes to mind is buildings.

Abstraction: You never build a building. You build a house, an apartment building or an office building.

Polymorphism and Inheritance: An apartment building is a building, but also implements the functions of Habitat. That would be an interface. So, you have

interface Habitat;
abstract class Building;

and then

class ApartmentBuilding extends Building implements Habitat{...

And this shows the basic construct (he, unintended pun) of OOP.

A singleton can be EmpireStateBuilding. There's only one, and if someone's asking for one, a reference to the existing one is given. Just before it was built, asking for an EmpireStateBuilding would create one single EmpireStateBuilding. So it's a singleton.

Now, the has-a relationship can be explained with a Wall object. Our abstract Building has a collection of Walls. A wall is not abstract, but rather concrete (pun #2), and can also be extended (pun #3?) to a InnerWall or OuterWall. The GreatWallOfChina is a singleton extending Wall.

So this analogy covers most of what's discussed when teaching OOP.

$\endgroup$
1
$\begingroup$

When I saw a software engineer, I always ended up using personal pronouns, when talking about classes and objects. “He does this, and tells her, then she …”. They are like people working together. And sometime they model objects.

Therefore classes are used to model subjects and objects.

We often, for hard problems, would get a team together and act out a scene to work out what the software should do. Some of the roles where played by the software developers, others by index cards, boxes, a calculator (to represent a math library), and various other props. We would act a scene several times, making improvements until it worked. We would then make notes, and then go away and implement the code.

We did not make any distinction (consciously) of subject vs object. Objects can be a bit subjecty and subjects can be a bit objecty.

$\endgroup$
  • $\begingroup$ Yeah, OO is a loose metaphor, which suffers when we try to be too rigid about it. I like the idea of "acting out" what a program needs to do. $\endgroup$ – user737 Jul 22 '17 at 13:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.