By

Now That's Classy

Technical Blog Post 5

Ruby is an object-oriented language, meaning it uses classes and objects to represent concepts. Classes are template for objects. They include a collection of variables representing internal state and methods that operate on that state. Some built-in classes include String, Integer, Time, Array, and Range. Objects are single instances of a class. For example, “I am a string” is an object of the String class. If you write “I am a string”..upcase, you are calling the upcase method that is defined in the String class.

Let’s look at a more complex example, where we will create a Family class that defines properties and methods that all families have in common.

Instance Variables:

The @ symbol in front of our features (last_name, address) indicate that they are instance variables. Instance variables, which are an object’s variables, last as long as an object does and can be called by any instance method of the object, not just the method it is defined in. Conversely, variables with a local scope (those without a symbol in front of them) only interact with the method they are defined in. We can also have a class variable, indicated by two @@ symbols, which are available to any instance of a class. If we called Family.describe, the string “Family is important” would be outputted. There are also global variables, indicated by a $ symbol, which are available anywhere in a program. Global variables are not common.

Attribute accesor:

Because instance variables are only accessible to instance methods and not the outside world, we have to define reader and writer methods, or getters and setters, to expose an object’s instance variables and let a user set them outside the class definition. To do this, we write attr_reader, attr_writer, or attr_accessor, followed by the instance variable names as symbols preceded by a colon, at the top of a class definition.

Now that we’ve touched on instance variables and getters and setters, let’s go back to our example and create a Johnson_Family object with its last_name and address specified in the parameters:

Because introduce is a method defined in the Family class, we can call it on Johnson_Family like this: Johnson_Family.introduce. This would output “We are the Johnson family”.

Inheritance:

What if we wanted Johnson_Family to have certain features that other families don’t have? For example, let’s say Johnson_Family is a military family and we want to specify what base they live on. We don’t want military_base to be a feature of all Family objects, but we want it to be a feature of some. We could create a new subclass, Military_Family, which inherits all the properties of the parent class Family but which also has features of its own. Then, when we create a new instance of Military_Family, the object will have not only a military_base feature but also a last_name and address.

Using the “<” symbol below lets Military_Family inherit all the properties of the Family class. Super indicates that we are asking the parent of the current object to invoke a method of the same name. Note that a class can only inherit from a single class at a time (i.e. it can inherit from a class that inherited from a class that inherited from a class, but not from multiple classes at once).

We would then instantiate Johnson_Family like this:

Now you know the basics of classes and objects in Ruby. For further exploration, check out modules, mixins, and private/public/protected methods. Goodbye for now…“class” is no longer in session.