These free mini-courses will give you a strong foundation in web development. Track your progress and access advanced courses on HTML/CSS, Ruby and JavaScript for free inside our student portal.
Scroll down...
Classes are essential to an object-oriented approach. They are like blueprints -- you specify how an object should look and act so you can make as many copies as you need to later. They allow you to DRY up your code by putting the methods used by these objects in one central location. They also help you encapsulate your data better and organize your code more coherently.
More generally, classes are the blueprint for producing objects like Dogs or Vikings or blog Posts. Each object has behavior and state . The class defines what behavior is available to each object via methods and keeps track of that object's state using instance variables.
Classes are incredibly powerful. To get you familiar with them, we'll start by looking at some pretty literal examples like the objects referenced above. Many of the things you model in web programming will resemble this fairly literal set of objects but many more will actually be a bit more abstract. For instance, in Rails there is a Router class which packages up all the functionality to send incoming HTTP requests into the right area of your application. Our ultimate goal is for you to be able to deploy classes to solve these more abstract use cases.
In this lesson, though, we'll start with the basics of classes. Over the next several lessons, we'll show you how instance variables, instance methods, class variables and class methods are used to flesh out the state and functionality of your class (and its instances).
Our goal for the next several lessons is that you become quite familiar with the idea of classes and the particulars of their use. We'll cover how classes are defined, how instances of these classes are instantiated, and how to give them necessary functionality with methods and variables.
There are generally three good indications that you should package up your functionality into a class instead of individual methods or objects:
As you get deeper into OOP, the rule of thumb becomes more like "just make a class for it".
You can go a long way by using the basic data structures Ruby gives you like arrays and hashes. Let's say you're building a game and the player needs a bunch of attributes stored. A hash seems like a pretty reasonable way to do this:
> player1 = {:health => 100, :name => "Oleg", :attack_damage => 12}
#=> {:health => 100, :name => "Oleg", :attack_damage => 12}
You might assume that the game script handles all the possible interactions between your player and any other game objects. That should already be a warning sign that you might have a "god" script that does too much...
But what if you want to bring your player to life and actually give it functionality of its own like walk
ing or heal
ing or attack
ing? It's best to bring the hash to life by making it a class and including any desired functionality as instance methods.
We'll dive into the details of this below, but a simple version of your class might look like:
class Viking
def initialize(name)
@name = name
@health = 100
@attack_damage = 12
end
def attack(victim)
#... code to attack ...
end
end
# IRB
> player1 = Viking.new("Oleg")
#=> #<Viking:0x007fc20d855ad0 @health=100, @name="Oleg", @attack_damage=12>
This allows your player to attack other players and gives you the added benefits of being able to create a new player by simply specifying the name. This will come in handy if you're building an army with 1000 Vikings.
In a more general sense, when you just store your Viking
's name
, age
, health
, and strength
in a hash, it just kind of sits there. When you want to make an army of Viking
s who can do stuff like eat
, travel
, sleep
and, of course, attack
, you need to make it a class of its own.
Think of a class as a container for methods and variables that you'll want each object to have access to:
class Viking
# put your methods and variables here!
end
So, in this case, the big reasons for us using a class is because we wanted our object to actually do things and we wanted to be able to make lots of them.
The class name is always capitalized and, for multiple words, uses CamelCase (capitalized with no spaces) not the snake_case (lowercase with spaces as underscores) you've typically seen for variables and methods. The name should be the singular "thing" you'll be building.
# WRONG -- plural
class VikingWarriors
# WRONG -- snake case
class Viking_Warrior
# WRONG -- lowercase
class vikingwarrior
# RIGHT
class VikingWarrior
To be able to amass a horde of 1000 Viking
s, you need a way to create new ones. Each time you do that, it's called Instantiating a new Viking
. You use a special new
method to do that.
This isn't anything new -- you've done it many times over for the Array
class already:
> my_arr = Array.new
#=> []
new
is a Class Method, which means that you call it on the class (in this case Array
) and not the specific instance of that class (which would be my_arr
here). We'll talk about these in detail a bit later on.
When you call that method, it creates a new instance (object) of that class and then runs a special method inside the class called initialize
, which will set up that class to be ready for use. If you pass variables to your class when you create it with the new
method, they will be available to the initialize
method.
Your Viking
class would start by looking like:
class Viking
def initialize(name, age, health, strength)
# set up your new viking however you want to
end
end
Running the initialize
method upon instantiating a new object automatically occurs and it's a very common programming pattern that Ruby is just borrowing.
The important bits of code from this lesson
# Instantiate a class
oleg = Viking.new("Oleg", 100, 19, 8)
This was probably mostly a refresher for you but at least we're all on the same page now. We'll dig deeper into the workings of classes over the next several lessons when we cover instance variables/methods and class variables/methods.