1.Why Classes?
"Matz".length
# ==> 4
the "Matz"
object is a string with a .length
method and a length attribute of 4
But what exactly makes "Matz"
a string? The fact that it's an instance of the String
class. A class is just a way of organizing and producing objects with similar attributes and methods.
2.Class Syntax
A basic class consists only of the
class
keyword and the name of the class. Check it out:class NewClass
# Class magic here
end
Our NewClass
has the ability to create new Ruby objects of class NewClass
(just like "Hello!"
is a String
and 4
is a Fixnum
). By convention, class names start with a capital letter and use CamelCase instead of relyingonunderscores.we started our class definition off with a method called
initialize
. You can think of initialize
as the function that "boots up" each object the class creates.class Person
def initialize
end
end
4.What's in a @name?
@
before a variable to signify that it's an instance variable. This means that the variable is attached to the instance of the class. For example,class Car
def initialize(make, model)
@make = make
@model = model
end
end
kitt = Car.new("Pontiac", "Trans Am")
creates an instance, kitt
, of the class Car
. kitt
has his own @make
("Pontiac") and @model
("Trans Am"). Those variables belong to the kitt
instance, which is why t5.Instantiating Your First ObjectWe can create an instance of a class just by calling
.new
on the class name, like so:me = Person.new("Eric")
Classes and Objects
6.Scope it Out
Another important aspect of Ruby classes is scope. The scope of a variable is the context in which it's visible to the program.
It may surprise you to learn that not all variables are accessible to all parts of a Ruby program at all times. When dealing with classes, you can have variables that are available everywhere (global variables), ones that are only available certain methods (local variables), others that are members of a certain class (class variables), and variables that are only available to particular instances of a class (instance variables).
The same goes for methods: some are available everywhere, some are only available to members of a certain class, and still others are only available to particular instance objects.
It may surprise you to learn that not all variables are accessible to all parts of a Ruby program at all times. When dealing with classes, you can have variables that are available everywhere (global variables), ones that are only available certain methods (local variables), others that are members of a certain class (class variables), and variables that are only available to particular instances of a class (instance variables).
The same goes for methods: some are available everywhere, some are only available to members of a certain class, and still others are only available to particular instance objects.
7.Naming Your Variables
@
. This isn't just a Ruby convention—it's part of the syntax! Always start your instance variables with @
.Class variables are like instance variables, but instead of belonging to an instance of a class, they belong to the class itself. Class variables always start with two
@
s, like so: @@files
.Global variables can be declared in two ways. The first is one that's already familiar to you: you just define the variable outside of any method or class, and voilà! It's global. If you want to make a variable global from inside a method or class, just start it with a
$
, like so: $matz
.class MyClass
$my_variable = "Hello!"
end
puts $my_variable
8.For Instance...
For example, instance variables belong to a particular object (or "instance"). Let's get in some practice with instance variables!
Go ahead and add
age
and profession
parameters to the initialize
method, then set these equal to instance variables in the body of the method. Use the name
/@name
example as a guide. class Person
def initialize(name,age,profession)
@name = name
@age = age
@profession = profession
end
end
9.Twice the @, Twice as Classy
We can create class variables by starting a variable name with two
@
symbols. Class variables are attached to entire classes, not just instances of classes, like so:class MyClass
@@class_variable
end
Because there's only one copy of a class variable shared by all
instances of a class, we can use them to pull off some cool Ruby tricks.
For example, we can use a class variable to keep track of the number of
instances of that class we've created.@@people_count = 0
def initialize(name)
@name = name
@@people_count += 1
end
def self.number_of_instances
return @@people_count
end
end
matz = Person.new("Yukihiro")
dhh = Person.new("David")
puts "Number of Person instances: #{Person.number_of_instances}"
Inheritance
11.Watch Your Step
Inheritance is the process by which one class takes on the attributes and methods of another, and it's used to express an is-a relationship. For example, a cartoon fox is a cartoon mammal, so a CartoonFox class could inherit from a CartoonMammal class. However, a Wizard is not an Elf , so it shouldn't inherit from the Elf class (even if they have a lot of magical attributes and methods in common). Instead, both Wizard and Elf could ultimately inherit from the same MagicalBeing class.
12.Inheritance Syntax
In Ruby, inheritance works like this:
class DerivedClass < BaseClass
# Some stuff!
end
where the derived class is the new class you're making and the base
class is the class from which that new class inherits. You can read "<
" as "inherits from."
Sometimes you'll want one class that inherits from another to not only take on the methods and attributes of its parent, but to override one or more of them.
For instance, you might have an
This new version of
For instance, you might have an
Email
class that inherits from Message
. Both classes might have a send
method that sends them, but the e-mail version may have to identify
valid e-mail addresses and use a bunch of e-mail protocols that Message
knows nothing about. Rather than add a send_email
method to your derived class and inherit a send
method you'll never use, you can instead just explicitly create a send
method in the Email
class and have it do all the email-sending work.This new version of
send
will override (that is, replace) the inherited version for any object that is an instance of Email
.def initialize(name)
@name = name
end
def fight
return "Punch to the chops!"
end
end
class Dragon < Creature
def fight
return "Breathes fire!"
end
end
14.When Good isn't Good Enough
On the flip side, sometimes you'll be working with a derived class (or subclass) and realize that you've overwritten a method or attribute defined in that class' base class (also called a parent or superclass) that you actually need. Have no fear! You can directly access the attributes or methods of a superclass with Ruby's built-in
The syntax looks like this:
super
keyword.The syntax looks like this:
class DerivedClass < Base
def some_method
super(optional args)
# Some stuff
end
end
end
When you call super
from inside a method, that tells Ruby to look in the superclass of the
current class and find a method with the same name as the one from which
super
is called. If it finds it, Ruby will use the superclass' version of the method.Dragon
's definition of fight
with the keyword super
. (No need to pass any arguments to super
, since Creature
's fight
method doesn't take any.)class Dragon < Creature
def fight
puts "Instead of breathing fire..."
super
end
end
15.There Can Be Only One!
However, there are instances where you want to incorporate data or behavior from several classes into a single class, and Ruby allows this through the use of mixins.if you want to end a Ruby statement without going to a new line, you can just type a semicolon. This means you can write something like
class Monkey
end
on just one line: class Monkey; end
. This is a time saver when you're writing something very short, like an empty class or method definition.class Dragon < Creature; end
class Dragon < Person; end
See how we're trying to get
Dragon
to inherit from Creature
and Person
? We'll get a superclass mismatch for class Dragon
error if we try this. Project
2.Create Your Class
Create a class called
Computer
and give it an initialize
method that takes no parameters. The body of initialize
should be empty.class Computer
def initialize
end
end
3.Fancify Your Initialize Method
Update
initialize
to take two parameters, username
and password
. In the body of initialize
, set the instance variables @username
and @password
(respectively) to these parameters.In your
initialize
method, you'll also want to create a @files
instance variable and set this to an empty hash. This is so we can keep track of our files later!class Computer
def initialize(username,password)
@username = username
@password = password
@files = {}
end
end
4.Have a Little Class
Add a class variable called
@@users
to your Computer
class. Set it equal to an empty hash.In your
initialize
method, set @@users[username] = password
so that your @@users
hash keeps usernames as keys with each username's password as the associated value.class Computer
@@users = {}
def initialize(username,password)
@username = username
@password = password
@files = {}
@@users[username] = password
end
end
5.Getting More Creative
- Inside your
Computer
class, define a method calledcreate
with a single parameter,filename
. - Inside
create
, declare a variable calledtime
and set it equal to the current time (usingTime.now
). - Next, inside
create
, add a new key/value pair to the@files
hash. Use thefilename
key to store the valuetime
. - For the final step in
create
, pleaseputs
a message telling the user that a new file was created. Feel free to put in any information you like; the one we used in exercise 1 printed the filename, the username, and the time.
@@users = {}
def initialize(username,password)
@username = username
@password = password
@files = {}
@@users[username] = password
end
def create(filename)
time = Time.now
@files[filename] = time
puts "A new file was created,filename: #{filename},username: #{username}, time: #{time}"
end
end
6.Who're the Users?
Because
@@users
is a class variable, we'll use a class method to grab it. Most of the methods you've seen so far are instance methods—they work on a particular instance/object, such as "matz" or "blixy". A class method belongs to the class itself, and for that reason it's prefixed with the class name, like so:class Machine
def Machine.hello
puts "Hello from the machine!"
end
end
- Add a new class method to your
Computer
class calledComputer.get_users
. It should have no parameters. - Your new
Computer.get_users
method shouldreturn
the@@users
class variable.
@@users = {}
def initialize(username,password)
@username = username
@password = password
@files = {}
@@users[username] = password
end
def create(filename)
time = Time.now
@files[filename] = time
puts "A new file was created"
end
def Computer.get_users
return @@users
end
end
7.Instantiation Nation
I think you're missing an at symbol (@) on the username
ReplyDeleteclass Computer
@@users = {}
def initialize(username, password)
@username = username
@password = password
@files = {}
@@users[username] = password
end
def create(filename)
time = Time.now
@files[filename] = time
puts "#{filename}, was created by, #{@username} at #{time}"
end
end