Rails Mama’s Guide to Object Oriented Programming Part 7: Polymorphism

After a brief intermission, we now move on to the third and final pillar of Object Oriented Programming: Polymorphism.


This is part 7 of a series. To get the most out of these posts, read them in order:

Part 1: Objects
Part 2: Classes
Part 3: Multiple Inheritance
Part 4: Recap & Quiz

Part 5: Encapsulation

Part 6: Data Types


Part 7: Polymorphism

Going back to the example in Part 1, we have a problem: We’re stuck on a road trip and need to pee into an empty Coke bottle. It’s basically the same action as peeing into a toilet, but there are some major differences in how the action gets handled.

When pee goes into a toilet, it hits water, making a splash. It also changes the state of the toilet to “In need of a flush”.

When pee goes into a Coke bottle, it doesn’t hit water and the Coke Bottle can’t be flushed, but it does change the state of the Coke Bottle to “Needs to be thrown out and/or chilled in ice and passed off as Mountain Dew”.

What we need is for the Person Class to be able to send the same message “empty bladder into”  to multiple different objects (toilet, coke bottle, bidet, urinal) and get different results.

Enter the great and mighty Polymorphism!! Da-ta-da!


Polymorphism is just a big, fancy word for “the ability to send the same message to different objects and get different results.”

We’ve already talked about one way of doing this: Inheritance.

Over the next few posts, I will detail the other types of Polymorphism, but first let’s review how we could achieve Polymorphism through Single Inheritance.

In this example, I’m going to write some very simple Ruby code and explain what’s going on:

class PeeReceptacle

   def receive_pee

       puts “Thanks for the pee.”

   end

end

PeeReceptacle is a Class, which you probably guessed by the word “class”. The second line defines (def) a method called receive_pee. The third line tells us what the receive_pee method will do when you call it. In this case, it will print “Thanks for the pee” to the terminal. The last two lines use “end” to close the definition of the method, and then to close the Class.

Get out the cigars, because our PeeReceptacle Class is going to have twins!

class Toilet < PeeReceptacle

   def receive_pee

      puts “Thanks for the pee. You should probably flush me before your dog comes in for a drink.”

   end

end

class CokeBottle < PeeReceptacle

    def receive_pee

       puts “Thanks for the pee. I hear your boss really likes Mountain Dew.”

    end

end

pee_bottle

Congratulations PeeReceptacle! You are now a Parent Class! (Hope you didn’t like sleep.)

See how the first line of each Child Class has “< PeeReceptacle”? That means “this class inherits from PeeReceptacle”.

Our Child Classes inherit all the methods of the Parent Class, BUT if both classes have the same method defined, the method of the Child Class wins out.

That means that if we call the receive_pee method on a CokeBottle, we will get “I hear your boss really likes Mountain Dew”, but if we call the same method on Toilet, we’ll be reminded to flush.

Now all we have to do is set up a method in the Person Class called “empty_bladder_into”, and make it trigger the receive_pee method of whichever class it is used on.

BAM! Polymorphism!


 

Now you try!

Design another class that would inherit from PeeReceptacle. What will you call it? What will it’s receive_pee method do?

Leave a comment with your answer.

Big kudos to anyone who a) makes me laugh, b) grosses me out, or c) uses a Ruby method I’ve never seen. Enormous kudos for anyone who achieves all 3 goals.

Advertisements

Rails Mama’s Guide to Object Oriented Programming Part 6: Data Types

We’ve talked about 2 of the 3 “Pillars of Object Oriented Programming”: Encapsulation and Inheritance. Before we can talk about the third, “Polymorphism”, it helps to understand Data Types.


This is part 6 of a series. To get the most out of these posts, read them in order:

Part 1: Objects
Part 2: Classes
Part 3: Multiple Inheritance
Part 4: Recap & Quiz

Part 5: Encapsulation


Part 6: Data Types

My favorite analogy for Data Types comes from a super-duper-academic article written in 1985. It’s a great article, but I’ll give you the playful, non-academic version:

Once upon a time, all the data in the world was naked. It frolicked around in the Garden of Computer Science, with nary a leaf to cover it’s unmentionables. It was naked and free, and totally unprotected from poison ivy.

As the Data population grew, it become more and more dangerous for Data to run around naked. It was one thing for Data to frolic around alone in a peaceful garden, but if it tried walking into a busy New York subway that way….well, let’s just say it might get misused.

To protect their Data, programmers began to send it out into the world dressed in Data Types.

Much like clothes, Data Types make a statement about what to expect from Data, and also make it less likely for that Data to be used in an inappropriate way.

Picture a girl in with a pink, frilly dress and a tiara. She is making the statement “I am a princess.” She is also sending a message about what would be an appropriate or inappropriate way to interact with her.

Appropriate: “Would you like some tea, your Highness?”

Inappropriate: “Let’s jump in that mud pit and wrestle some pigs!”

princess_mud

Here are a few of the Data Types you’re likely to find in your programming language’s wardrobe:

String: Says “Treat me like a word or sentence”.

  • Appropriate things to ask of a String: “Print yourself.” “Join with this other string to make a longer string.”
  • Inappropriate things to ask of a String: “Divide yourself by 3 and tell me what the remainder is”.

Boolean: Says “I am either True or False. There is no gray area here.”

  • Appropriate: “Tell me if you’re true or false”.
  • Inappropriate: “Multiply yourself times 10.”

Integer (or Fixnum): Says “I am a nice, round number with no decimal places.”

  • Appropriate: “Tell me if you are larger or smaller than the number 14.” “Multiply yourself times 20.”
  • Possibly Inappropriate: “Do some division and give me a precise answer.” (This is a tricky one. Some languages, such as Ruby, will take a problem like 3/2 and say “Hey, they gave me 2 Integers, so they must want an Integer back.” Since the answer is 1.5, and that is NOT an Integer, it has to be either rounded up or rounded down, so you get a silly answer like 3/2 = 1.)

Float: Says “I am not so pretty and round, but at least I know what 3 divided by 2 is.”

  • Appropriate: “Divide yourself by 2 and give me a precise answer.”
  • Inappropriate: “Tell me if you’re true or false.”

There are many other Data Types, and different languages use different ones, but this should illustrate their purpose. Data Types are just a wrapper around your data, which tells the program what to expect of it, and how it can and cannot be used.


 

Ready to Learn More? Check out Part 7: Polymorphism

Rails Mama’s Guide to Object Oriented Programming Part 5: Encapsulation

This is part 5 of a series. To get the most out of these posts, read them in order:

Part 1: Objects
Part 2: Classes
Part 3: Multiple Inheritance
Part 4: Recap & Quiz

According to Wikipedia (the Patron Saint of Crowd-Sourced Information):

“Encapsulation, Inheritance , and Polymorphism are the three pillars of object-oriented programming.”

So far, we’ve talked about one of those concepts: Inheritance. Now, we’ll talk about Encapsulation.

Encapsulation is a technique in Object Oriented Programming that allows you to restrict the ways a user can interact with an Object.

Part 5: Encapsulation 

Every parent knows how hard it is to feed their kids broccoli, and I frequently wish I could just smash some green vegetables up against my children’s skin and have them magically absorb the nutrients.

broccoli

Unfortunately, while that might work great for broccoli, it would leave my kids’ internal organs quite vulnerable. Kids have a tendency to touch a lot of disgusting stuff, and we wouldn’t want them to absorb worm guts and puppy drool.

To protect the important organs inside the Child Object, we’re going to create an Interface, or “method for interacting with an object”. Our Interface is a method called “Eat with Mouth”. Now food can only go into a Child Object via the Eat with Mouth Interface. This Interface also has a Taste feature, which Validates that anything going in is not “icky”.

Unfortunately for us, Broccoli does not pass the Ickiness Validation.

As you can see, there are upsides and downsides to Encapsulation.

The upside is that it protects the internals of your Object from being affected by Objects and Methods that you don’t want it exposed to. (This is a pretty enormous upside).

The downside is that it makes it harder for us to access those internals when we want to do something unconventional. It’s the technological equivalent of having to coo “Here comes the choo-choo” just to get one bite of broccoli past the Taste Validation. (Not too big a sacrifice to prevent liver failure).

In a computer program, the “Internal Organs” that you are trying to protect are bits of information. If important pieces of information get altered, your program might do something unexpected like Crash Whenever a User’s Name is Bob or Build a Militia and Invade France.

Encapsulation is the process of bundling our data and methods together, in order to protect that data from being accessed or changed in ways that it shouldn’t. Hiding information is called….wait for it…..

Information Hiding.

You might hear the term Information Hiding used as a synonym for Encapsulation, but I like to think that “Information Hiding” is the purpose behind Encapsulation, and Encapsulation is the process by which information is bundled with methods and hidden from meddling users.

There is, however, apparently some debate around the exact definitions, and if you care about that, Google knows better than I.

Next up: Part 6: Data Types

Rails Mama’s Guide to Object Oriented Programming Part 4: Recap

This is part 4 of a series. To get the most out of these posts, read them in order:

Part 1: Objects
Part 2: Classes
Part 3: Multiple Inheritance
Part 4: Recap & Quiz

Part 4: Review of Objects, Classes and Inheritance

We’ve been over several Object Oriented Programming (OOP) concepts in the last 3 posts, so it’s time to recap and take a quiz!

Let’s combine all of those concepts by imagining a program that would help Santa deliver presents.

A Function (or Method) might look something like this:

Deliver Present From Deliverer To Recipient

Procedural Programming is just a list of step-by-step instructions. If you say, “Deliver Elf From Present to Child”, the program says, “Yes, ma’am!” and you have a child wondering why a present just gave him an elf.

That would be awkward, so we’re going to use OOP instead. That will allow us to treat each noun as an object, and restrict what those objects can and can’t do.

First, let’s make our list of Objects:

  1. Santa
  2. Elfie the Elf
  3. Buddy the Elf
  4. Toy Car
  5. Rag Doll
  6. Little Jimmy
  7. Little Janey
  8. Jolly the Elf-Child

Now, let’s break those Objects down into Classes:

  1. Deliverers: Santa, Elfie, Buddy
  2. Presents: Car, Doll
  3. Recipients: Jimmy, Janey, Jolly the Elf-Child

These classes work fine for our current method, but what if we add more methods like “Choose Recipient for Present” or “Make Present”? We don’t want Santa making presents (never give him a hammer), and we don’t want elves making decisions about presents (Wooden shoes for everyone!).

We also don’t want to have to write all our delivery-related methods twice, and imagine if we get desperate and have to start using reindeers and snowmen to make deliveries as well? We’re going to be re-writing the same methods over and over!

It’s time to make some sub-classes using Inheritance.

Parent Class: Deliverers

Methods: “pick up present”, “go down chimney”, “place present under tree”

Elf Class (Inherits from Deliverer Class)

Methods: Deliverer methods + “Make presents”

Santa Class (Inherits from Deliverer Class)

Methods: Deliverer methods + “Choose Recipient for Present” + “Say ‘Ho ho ho!'”

Now let’s look at Elfie. Elfie is an Elf, and Elves are Deliverers. That means Elfie is an Elf AND a Deliverer.

But what about Jolly the Elf-Child?

Jolly can receive presents, because he is a child, but when the workshop is behind schedule, Santa might need him as a deliverer or toy-builder too. How do we handle that?

One way is through Multiple Inheritance. Jolly can Inherit from both the Elf Class and the Child Class. But…remember how that can get messy if they have different methods with the same name?

Let’s use Single Inheritance instead.

We’ll create an Elf-Child class that inherits from Elf, and make a Module with the important Child methods.

Module methods: “receive presents”, “flip out over presents”, “believe in Santa”

That module is a “Mixin”, because we are “mixing it into” a class it would not normally be part of.

Now You Try:

(No wrong answers, just exercises in thought):

Mrs. Claus can deliver presents, make decisions about who receives presents, and also bake cookies.

  1. In the above situation, what are the Objects?
  2. What Methods Does Mrs. Claus have?
  3. Would she belong to an existing class, or would you create a new class?
  4. With Multiple Inheritance, what classes could a Mrs. Claus Class inherit from?
  5. If you used Multiple Inheritance, what methods could overlap between those Parent Classes (for example, could a child and an elf sleep differently?)
  6. With Single Inheritance, what one class would you choose for Mrs. Claus to inherit from?
  7. What other methods would you “Mix in”?

Feel free to leave a comment with your take on the answers to these questions. I’ll be happy to give you feedback.

However, to be fair to yourself and others, please:

  • Answer the questions for yourself before reading others’ answers
  • If you comment on someone else’s answer, please make sure it is “constructive criticism” (Instead of saying “You’re wrong!”, nicely explain how the answer could have been improved in your humble opinion.) 

We are all Big Kids here, and I do not want to have to put any commenters in Time Out.

Want to Learn More? See Part 5: Encapsulation

Rails Mama’s Guide to Object Oriented Programming Part 2: Classes

This is part 2 of a series. To get the most out of these posts, read them in order:

Part 1: Objects
Part 2: Classes

In Part 1, we talked about what an Object is, and how they are useful.

In case you didn’t read it, or were distracted by all the exciting new terms for “taking a pee”, here’s a recap with some additional clarification:

In OOP (Object Oriented Programming):

  1. Instead of giving a list of step-by-step commands, we divide the program into objects and interact with those objects.
  2. Anything that can be described with a noun is an object. People, places and things are all objects.
  3. Objects have states (a.k.a attributes or properties). A toilet has a color and can be either flushed, unflushed, or clogged.
  4. Objects have actions (a.k.a. functions or methods) which they can perform. A toilet can flush or run over or smell horrid.

Now, lets look at classes.

Part 2: Classes and Inheritence

Let’s pretend you’re cleaning out your purse (or your man-purse, as the case may be). You bought one of those enormous designer bags that can be emptied out and held above your head in the case that your parachute fails to deploy, and you’ve packed it so full that you have to wheel it into the mall on a hand truck.

Now you want to smuggle a young child into the movie theatre, so you need to clear out your purse (or man-purse) to leave room for him.

You dump the contents on your table (it’s a big table), and think, “I really need to organize this junk.”

You decide to put all the objects in separate boxes with a label saying what they do, and what characteristics they have. This should make it easier to refill your parachute-man-purse with only the necessary items.

man_purse

There are about 30 pens in your bag, because you are one of those people that walks off with a pen even when it has a giant, garish flower taped to it.

Making a separate box and label for each pen would take forever, so you decide that they can be grouped together.

A pen may be blue or black, ball-point or fountain, but all pens have certain things in common. All pens have the actions “write” and “run out of ink”. All pens have the states “color”, “ink type”, and “company that it belonged to”.

In OOP, “pen” is a Class, and the bank-pen with the chain still attached is an Object that belongs to the “pen” Class (and, technically, to the bank).

You grab a box and start putting all the pens in the box. It’s going pretty well until you come across a pencil. It’s not a pen, but it does pretty close to the same thing, so should it go in the pen box or should it go in it’s own box?

The pencil does have the action “write”, and it does have the state “company that it belonged to”, but it does not have ink and it cannot run out of ink.

They are so similar that it seems wasteful to use a separate box, but you still want to separate the pens and pencils.

This is where Inheritance comes in. The pens and pencils are similar because they are both “writing instruments”.

Instead of having a “pen” box and a “pencil” box, you can have a “writing instrument” box. “Writing Instrument” is the Parent Class. The sticky note on the box will describe all the methods and states that all writing instruments have in common, such as “write”.

Then, inside that box, you will wrap a rubber band around the pens and label the bunch with the methods and states that are unique to pens, such as “ink type” and “run out of ink”. You do not need to note that it can write. We already know that because everything in the “writing instrument” box has the “write” method. It says so on the sticky note.

So, now we have:

Writing Instrument (Parent Class)

methods: “write”, “get stolen from business”

states / attributes: “brand”, “original owner”

Pen (Class that Inherits From Writing Instrument)

methods: “run out of ink”

states / attributes: “ink color”

(plus all the methods & states of it’s parent class)

Pencil (Class that Inherits From Writing Instrument)

methods: “get sharpened”

states / attributes: “eraser size”, “lead type”

(plus all the methods and states of its parent class)

Now the contents of your purse are all neatly organized into Classes and Subclasses. That is…until your toddler comes around and decides to “refactor” by dumping everything on the floor.

Liked this post? See Part 3: Multiple Inheritance.

Rails Mama’s Guide to Object Oriented Programming Part 3: Multiple Inheritance

This is part 3 of a series. To get the most out of these posts, read them in order:

Part 1: Objects
Part 2: Classes
Part 3: Multiple Inheritance

Part 3: Single Inheritance versus Multiple Inheritance

In the first 2 sections, we talked about how in OOP, everything is an Object, and using Inheritance, one object can belong to a Class, which “inherits” the states/attributes and methods/actions of it’s Parent Class.

For example, the “Toddler Son” Class inherits the “Unconsciously Dance When Eating Something Yummy” method from the “Rails Mama” Parent Class.

But wait–the Toddler Son Class has more than one parent! It also inherits from the Anti-Geek Papi” Class. That’s where the “Love for all things with wheels” attribute comes from. The Toddler Son Class has Multiple Inheritance! 

Multiple Inheritance is just what it sounds like: one class inherits methods and states from multiple Parent Classes.

Multiple Inheritance seems pretty cool, right? If we can control what’s inherited, we can take the good parts of the Rails Mama Class (i.e. “Love of Learning”) plus the good parts of the Anti-Geek Papi Class (i.e. “Ability to Take Everything Apart and Put It Back Together with no Left-Over Parts”), and Voila! Perfect Child Class!

There is one problem, though. Rails Mama and Anti-Geek Papi both have an “Entertain Oneself” method, and those methods, though they share a name and have a similar purpose, are very different.

If we run Rails Mama’s “Entertain Oneself” method, she will go straight to the nearest computer and/or bookshelf. If we run Anti-Geek Papi’s “Entertain Oneself” method, he will start dismantling the nearest car.

If Toddler Son inherits from both Parent Classes, what will happen if we run the “Entertain Oneself” method? Will he dismantle the nearest computer? Read the car manual? Or will the program go haywire, causing him to attempt to flush the cat down the toilet?

Yes, probably the last one. Multiple Inheritance can get quite messy if used improperly, and no one wants Fluffy to take a swirl.

While some languages, (C++, Python and Perl, for example) allow Multiple Inheritance, others (Ruby, Java, and C#) spare Fluffy the bath, and stick with Single Inheritance.

If Toddler Son is an example of Multiple Inheritance, Clone Daughter is an example of Single Inheritance. She takes all of Rails Mama’s methods and states, and none of Anti-Geek Papi’s.

But if we use Single Inheritance, how do we improve on the original Class? Does Clone Daughter have to inherit the “Drive a Car in Reverse” method from Rails Mama? The world would be a much safer place if she doesn’t.

Here’s where Mixins (a.k.a Traits) come in handy.

Instead of making “Daughter” from multiple Parent Classes, we simply clone “Rails Mama” (since she’s almost perfect anyway), and then Mix In the desirable traits from “Anti-Geek Papi”.

To keep Daughter from driving like a lunatic, we would simply create a Module, or “packet of code” that contains all of Anti-Geek Papi’s driving methods, and then we mix those into the “Daughter” class.

There are different ways of doing the mixing, each unique to the language, but the basic idea is “Please don’t let my daughter inherit driving and directional sense from me.”

And that, in an oddly-misshapen nutshell, is Single versus Multiple Inheritance.

Liked this post? See Part 4: Recap & Quiz.

Rails Mama’s Guide To Object Oriented Programming: Part 1

After my first few interviews for Junior Developer positions, I have seen that some of the hardest questions for me to answer are the ones that ask me to explain a concept in object-oriented programming.

In some cases, it’s because I’m not familiar with the concept, but in many cases, it’s simply that translating my practical experience with those concepts into words–especially words that don’t make me sound like an idiot–can be incredibly difficult.

I decided to research the concepts a bit more, and found that most resources give overly-technical definitions that are not useful to a beginner.

With that in mind, I’ve decided to create a multi-part series explaining OOP (Object Oriented Programming) in beginner-friendly terms.

So, with no further ado….

Part 1: Object Oriented Programming versus Procedural Programming

Have you ever played The Sims? How about Zelda? World of Warcraft?

Imagine if, instead of clicking on an ogre to fight it, or a toilet to pee in it, you had to choose an action from a giant list of commands.

In the Sims, you might be in the kitchen, but you would still have the option to “Flush the Toilet”. Worse, if you are in the bathroom, you would have so many irrelevant commands in your menu that by the time you found the “Take a Whiz” command, it would be too late. There would be a puddle on the floor, and you’d be searching for a “Take a Shower” command.

pee

That’s Procedural Programming. Some of the most popular Procedural languages are Fortran, COBOL and C, all created in the 60’s and 70’s.

In Procedural Programming, you give the computer a list of steps that it will take one by one, in order. Any procedure might be called at any point in the program, so if I write my program to 1) go to sleep in the bed and then 2) go pee, the program will not care that I forgot to write “Walk to the bathroom.” Oops–time to add a “Change the sheets” command.

Now, imagine if the player had the ability to create new commands. Your Sim REALLY has to pee, and you can’t find a “Take a Whiz” command, so you create one. You don’t realize that there’s already a “Tinkle” command that does the exact same thing, so you’ve just added an unnecessary command, cluttering up the menu even more. Worse, there are a hundred other users creating things like “Flush my Buffers” and “Do a Wee”. Your action menu is getting fatter by the second!

Then somebody came along and said, “Stop!” We’re going to organize these menus by object. Everything’s an object now: you’re an object, I’m an object, the toilet’s an object–everything. Each of those objects will have its own menu of actions (a.k.a functions or methods). It will also have states (a.k.a properties or attributes), so that a toilet can be clean or dirty, white or blue, empty or clogged.

Now, you can only pee by clicking on the toilet. If you click on the sink, you will not get a “Take a whiz” option, because that’s just nasty.

Now that your actions are organized, it’s easy to see that you have 100 methods for “Drain The Sleepy Weazel”, and you can pick one and delete the rest. No more puddles on the floor.

That’s Object Oriented Programming. C++, Java, Python, Ruby and PHP are examples of object-oriented languages.

Of course, the world of Object Oriented Programming is not perfect.

In a traditional Object-Oriented language, like Java, every object must be part of a Class. A class is just a group of similar objects that share methods (actions) and states (properties or attributes).

Sometimes it’s easy to figure out what Class an object should belong to. Clearly, that round white bowl that you are peeing into is part of the “Toilet” class.

And what about the Bidet, or the Urinal? You pee into it, and it can be clean or dirty, clogged or unclogged. It shares many of the same actions and attributes, so it should probably still be part of the Toilet class.

But what if you’re on a long car ride and have to pee into an empty Coca Cola bottle? Should that bottle be part of the Toilet class, since you’re peeing into it, or should you create a Soda Bottle class, even though you would normally think of a Soda Bottle as something you would drink out of, not pee in.

This is where things get complicated with Object Oriented Programming, but luckily there are several techniques for dealing with these conundrums, which I will address in a later blog post.

 Liked this post? See Part 2: Classes.