First steps with Ruby classes
Lately, we’ve been spending a lot of time at Dev Bootcamp learning how to organize objects and model behavior with classes in Ruby. That’s a really generic description, so here’s an example of some of the fun you can have by creating your own classes.
Let’s imagine we want to build some kind of a dog simulator, like The Sims: Dog Edition. In this awesome new game, we can create countless dogs and watch them interact in a virtual world. But, all dogs are unique. Breeds can vary in their physical characteristics and behaviors. And while dogs of the same breed are often similar, there’s lots of variation within any given breed, too. How can we model this?
Let’s start off with a general
There’s four important parts to the
attr_readerline creates getter methods for each of the variables listed. In other words, this allows us to retrieve the value of those variables from outside the object.
initialize, a new
Dogobject requires that we give it a name, and characteristics for the
Dogare automatically generated. By default, every new
Dogwill have four legs and are of breed “unknown”, and have random values (from 1 to 10) on stubbornness, friendliness, and intelligence.
barkmethod gives a
Dogobject the ability to bark.
profilemethod will print out several of a
We could create a new
Dog object called
fido, representing a loveable but generic dog named, well, Fido:
Dog class lets us generate dogs for our dog simulator, and every new dog will have a name, some random characterstics, and a way to bark. Let’s make it a little more sophisticated and add an even more specialized kind of
Dog class to represent the revered Boston Terrier breed.
Mia, a Boston Terrier, stares into your soul
Here’s a start to defining the
BostonTerrier class builds on our existing
Dog class and adds a few new wrinkles:
- When defining the class,
BostonTerrier < Dogindicates that
BostonTerrieris a subclass of
Dogand will inherent all of its properties.
- Boston Terriers tend to be very stubborn and very affectionate, so we want to reflect that somehow when new one are created. By definining
initializehere and using
super, we inherent the same initialization method as the parent (or super) class
Dogand add a twist: the randomly generated characteristics for Boston Terriers come from more specific ranges. This ensures that new Bostons are high in friendliness and stubbornness. We don’t modify how intelligence is initialized, so that could still be anything from 1 to 10, as defined in the parent
- We redefine the
barkmethod, because Bostons are definitely more yip yip than woof woof. The
Dogclass already has a
barkmethod, and this new yip yip
barkis only available to Bostons. Non-Bostons still have the original woof woof bark.
- Finally, we add a special new ability just for Bostons:
So let’s make a Boston Terrier named Mia and see her in action:
We can keep going, too! Here’s a subclass for Shetland Sheepdogs, another friendly breed known for their smarts and knack for herding:
ShetlandSheepdog class inherents all of the generic
Dog properties and has a unique method,
herd, which takes another object as a parameter. Now our dogs can interact! Let’s make a
Shetland Sheepdog named Shellie, and have her try to
Ok, so there isn’t a whole lot of drama in our dog universe yet. But, you can probably imagine some ways we could improve the
herd method, e.g., making the outcome dependent on the friendliness of two dogs involved. We could also add another layer to our hierarchy, between generic dogs and specific breeds, which would group different types of breeds (herding dogs vs. lap dogs) and could simplify our breed classes.
Just the little bit I’ve learned about classes and inheritance has been very powerful and has got me thinking about objects in a much more structured way. It’s pretty exciting stuff, but this is only the very beginning. If you’d like to carry on my canine version of the Sims, knock yourself out, but let me know when the checks start rolling in.