Classes in Ruby
Reading
So far we have seen how Ruby tracks information (also called "data") via variables. We have also seen how Ruby can implement behaviors in methods.
For instance we can keep information about a person such as their name (a
String
) and their test score (an Integer
) in variables.
name = "Gavin"test_score = 42
We've also seen how we can have a method that returns a description that combines the name and the score:
def description(person_name, person_test_score)return "The person named #{person_name} scored #{person_test_score}"endname = "Gavin"test_score = 42puts description(name, test_score)
However, both of these pieces of information and the behavior relate to each
other. Right now there is nothing that helps combine this into a single
representation. In order to associate the variables and the behavior into a
single concept (maybe named a Person
) we need to introduce the idea of a
class
Classes
Classes combine data (values) and behavior (methods) into one concept
Class
es are the template that describes what data, and what behavior we haveObject
s are instances of a class.Class
es are like cookie cutters, whereobject
s are like the cookiesInstances of objects
- We have already created many objects, just using the literal form of creating them.
- e.g.
name = "Gavin"
- e.g.
score = 42
- e.g. instance of a string:
name = String.new("Gavin")
But we can make our own classes. Let's make one to keep track of information about my dog.
class Dogendriley = Dog.newand we can define methods
class Dogdef agereturn 1endendAnd then call them:
riley = Dog.newp riley.age# => 1But what if there are two dogs with different ages?
Same behavior, different data.
Must provide the data to the object
We can give information to a new instance of an object via the
initialize
method.NOTE: This is similar to the
constructor
from JavaScript
class Dogdef initialize(age)@age = ageenddef agereturn @ageendend
- New type of variable, the instance variable, noted by the fact that it
starts with an
@
- Every instance of a
Dog
has it's own instance variables. - Now that we have an initialize method we must supply the age when creating each instance of a Dog.
riley = Dog.new(1)roscoe = Dog.new(7)
- We also added a behavior (method) to ask for the age of a
Dog
age
simply returns thisDog
instances@age
instance variable.- Thus the same behavior (knowing a
Dog
's age) but different data (the actual age of the dog) results in different action. attr_accessor
allows us to shortcut the defining of methods to return the value of the data (attribute) as well as set the value.
class Dogattr_accessor :age, :sound, :colordef initialize(age, sound, color)@age = age@sound = sound@color = colorendendriley = Dog.new(1, "woof", "piebald")puts "Riley is #{riley.age} years old, sounds like #{riley.sound} and is #{riley.color} in color"# Riley is 1 years old, sounds like woof and is piebald in color"# Riley gets a little olderriley.age = 2puts "Riley is now #{riley.age} years old, sounds like #{riley.sound} and is #{riley.color} in color"# Riley is 2 years old, sounds like woof and is piebald in color"
Inheritance
- Classes can have a
parent
class from which they gain all the data and behavior from but can extend with new data and behavior.
class GoodDog < Dogdef toys["bone", "tennis ball", "blanket"]endendgoodie = GoodDog.new(4, "woof", "brown")p goodie.toys# ["bone", "tennis ball", "blanket"]regular_dog = Dog.new(8, "aroooo", "black")p regular_dog.toys# NoMethodError (undefined method `toys' for #<Dog:0x00007fcede920090 @age=8, @sound="aroooo", @color="black">)
- Inheritance can be thought of as "is a" or "is a kind of"