Newbie Question: What is a class for?

M

Matthias Borgeson

Hello all-

I am a newbie to Ruby and have just recently gotten the hang of using
methods to hop in and out of the main body of my programs and am moving
to my next concept.

I am now trying to grasp what a class isand what is is for. I understand
that there a bunch of different classes, but how does that help me?

While I think of methods as little tools I can create to do things
whenever I want in the main program, I have no idea how a class used? I
have the Pickaxe and Chris Pine's book, but whle describing classes,
neither text really helps me understand what a class is and how it
functions in a ruby program.

I looked through my C++ book to understand methods and how they are
anologous to functions, but now I am just confused on the concept.

Any help or a point in the right direction would be appreciated

Thanks in advance

mfb
 
K

Kyle Schmitt

This is more than a ruby question, it's a basic OOP (Object Oriented
Programming) question.

Try thinking of it like this (insanely simplified, but it'll get you going)
A class is a collection of variables and methods.

If you haven't used objects, your variables so far have been global to
the program, or local to a method. With a class your variables can be
local to the method, local to the class, global to the class, or
(ugly) just plain global. I'm not going to go into how now, but if
you think about it, this makes life easier.

When someone has an object based off of your class, they can't see the
variables in the class (this isn't entirely true), they can only use
the classes methods. More than that, you can specify that some
methods can not be used outside, only inside (again, not entirely
true).

So when you make a class, you end up with this collection of methods,
some you can use outside, some only inside, and variables, which are
only on the inside. This is known as encapsulation.

It makes life easier in many many situations. For instance if you
have a stapler program you don't want to have a get_staples() method
as a global method that can be called anywhere. You want it bound to
a specific stapler.

class Stapler
#lots of cool code....
end

swingline = Stapler.new("red")
swingline.get_staples


Does that help at all?
 
M

MenTaLguY

Very loosely speaking, classes are a way of grouping together
functions that work with a particular sort of data structure or
object. Functions that have been grouped in a class are often
called "methods". Since every object has an associated class,
if you have an object, you have explicit access to the functions
for working with it.

One of the advantages of this is that you can have different
functions with the same name, differentiated by the sort
of object they work on (this is called "polymorphism").

For example, since we have a Float class and an Integer class,
we can define two functions called to_s; one in Float
(Float#to_s) that knows how to convert a floating-point number
to a string, and one in Integer (Integer#to_s) that knows how
to convert an integer to a string.

Then you can simply write foo.to_s to get the value of the
variable "foo" as a string, regardless of whether it is an
Integer or a Float. The class of the object on the left
side of the period determines which implementation of #to_s
to call. (The object on the left side of the period -- the
"receiver" -- shows up inside the called method as "self",
btw.)

Does that help a bit?

-mental
 
R

Rick DeNatale

Hello all-

I am a newbie to Ruby and have just recently gotten the hang of using
methods to hop in and out of the main body of my programs and am moving
to my next concept.

I am now trying to grasp what a class isand what is is for. I understand
that there a bunch of different classes, but how does that help me?

While I think of methods as little tools I can create to do things
whenever I want in the main program, I have no idea how a class used? I
have the Pickaxe and Chris Pine's book, but whle describing classes,
neither text really helps me understand what a class is and how it
functions in a ruby program.

I looked through my C++ book to understand methods and how they are
anologous to functions, but now I am just confused on the concept.

Any help or a point in the right direction would be appreciated

Thanks in advance

Classes do several things.

1) They hold the methods for one or more objects. These methods are
shared between those objects. For example consider this:

class A
def m
"hello"
end
end

The method m is available for any objects whose class is A to
respond when sent the message m.

2) Most classes can be used to create objects of that class. For example:

a = A.new

This creates an object whose class is A and makes the variable a
reference this new object. We can then send it the m message

a.m

and it will return "hello". This object is called an instance of A by
virtue of A being its class.

3) classes can form a hierarchy, let's make a new class:

class B < A
end

This syntax means that B is a subclass of A, or equivalently that A is
B's superclass. methods available to instances of a class are also
available to instances of any of its subclasses, so

b = B.new.m

will invoke the same method, as will just:

B.new.m

Subclasses can also override inherited methods:

class B < A
def m
"Howdy"
end
end

and now b.m will return "Howdy" instead of hello.

We can also make use of the inherited method in the overriding method

class B
def m
"#{super} there big fella!"
end
end

and now b.m will return "hello there big fella!"

4) Classes act as name spaces - but this is a bit advanced for this reply.

Every ruby object has a class, and classes themselves are objects, so
classes themselves can have methods, but again, I've probably already
given you enough to chew on.

And I'd strongly recommend that you hide that C++ book while you are
learning Ruby. It will confuse you more than it will help in the long
run since the two languages take some radically different approaches
and have radically different definitions of object orientation.
 
M

Morton Goldberg

While I think of methods as little tools I can create to do things
whenever I want in the main program, I have no idea how a class used


Expanding on this analogy, classes are tools for building more tools,
tools which can be much more powerful than a single method can be.
Because it holds variables as well as methods, an object created by a
class can maintain its state over the course of a computation. Think
of methods as tooling and the objects built from a class as complete
machine tools. A method is to a milling cutter as a object is to a
multi-axis milling machine.

Regards, Morton
 
M

Marc Heiler

I am now trying to grasp what a class is and what is is for.

They are a way to specifically shape your objects.

Tom the cat is probably of class Cat.
Jerry the mouse is probably of class Mouse.

Both might inherit from class Animal.
 
S

Sebastian Hungerecker

Matthias said:
I am now trying to grasp what a class isand what is is for. I understand
that there a bunch of different classes, but how does that help me?

In your code you use a lot of objects, right? Like 1 is an Integer object,
"hello" is a String object, /\d+/ is a Regexp object, [] is an Array object,
2..3 is a Range object (made out of two Integer objects) and so on.
You will have noticed that those objects all have a different set of methods:
You can do (2..3).each or [1,3,5].each, but you can't do 4.each or /la/.each.
You can do "I'm a string".length, but you can't do 3.length.
You can do 5.times, but you can't do "hello".times.
And it makes sense that it works that way, right? Cause what would the length
of an Integer be? Or what would it mean to execute a block of code "hello"
times?
As you can see, certain methods only make sense when used with a certain kind
of object. But how does Ruby know which objects are supposed to have which
methods? It know because of classes:
Every object is an instance of a class. "hello" is an instance of class
String, 5 is an instance of class Integer (Fixnum actually, but let's not
care about the difference at this point), 3..4 is an instance of class Range
and so on. Those classes describe what properties and methods their instances
have. "hello" has the methods length, gsub, tr and so on because they are
defined as methods of String. 2..5 and ["a","b","c"] have the method each
because in the class Range as well as in the class Array there is a method
called each. And so on.

But what can you do with classes? Well, you can use those classes by using
their instances. But you're already doing that. Even when you do 3 + 5 you're
using two instances of a class (3 and 5 of class Integer) and one method of
that class (the method +).
So what else can you do with classes? For starters you can extend the existing
classes. Let's say you have a method that "censors" a string:

def censor(string)
string.gsub(/./, "x")
end

You can use it like this: censor("hello world"), but now you're thinking that
it would be much more fun if you could use it like this: "hello world".censor
cause after all: all the other methods working with strings are used that way
too. So here's how you'd do that:

class String
def censor()
self.gsub(/./, "x")
end
end

Now you can type "hello".censor and get back "xxxxx" (how very useful, isn't
it). You will have noticed that where we previously said string.gsub we now
said self.gsub. Why's that? That's because the parameter string doesn't exist
anymore. We want to call the method like mystring.censor() without any
paramether. The method should work with the string that's in front of the dot
(also called the receiver of the method) and not with any parameter. So how
do we access the receiver? By using self. Inside a method definition self
will point to the object that the method has been called on. So when you
do "hello".censor, self is "hello" and if you do "bla".censor, self is bla.
Actually we wouldn't have even needed to use self in there: If you call a
method and you don't specify a receiver (i.e. you write foo() instead of
self.foo() ), the receiver is assumed to be self. So gsub(...) would be the
same as self.gsub(...).

So that's how you can extend existing classes. But sometimes that's not
enough. I mean think about what kind of objects does ruby have? Strings,
numbers, ranges of numbers, ranges of strings,... BORING! You're a people
person, you can't be expected to sit in the basement all day and only work
with numbers and strings. So ruby clearly needs a way to use people in your
program. So what we do is we create a class called Person that describes what
properties a person has and what he/she can do (what methods he/she has). So
that we can then use Person objects (I know you usually shouldn't think of a
person as an object, but here it's okay) in our code. Here's how to:
First you decide what properties a person should have. For now let's keep it
small and only let him/her have a name.

class Person
def initialize(firstname, surname)
@fname = firstname
@sname = surname
end

def name()
"#{@fname} #{surname}"
end

def firstname()
@fname
end

def surname()
@sname
end
end

So how do you use this class? Like this:

my_person = Person.new("John", "Smith")

new is a method that can be used on classes. It creates an instance of this
class and then calls a method called initialize on it (that's why we defined
such a method in our class). So now our initialize method gets called with
the parameters firstname and surname. All it does with those two is store
them: the value of firstname gets stored in @fname and the value of surname
in @sname. Variables starting with an @-sign are so called instance
variables. They're properties of an object. If a method sets an instance
variable to some value, all methods that get called on the same object can
now see this value when they access that variable.
Other than initialize there are three other methods: firstname, surname and
name. firstname and surname are boring. All they do is return the value of
the instance variable @fname or @sname respectively. name is a bit different.
It uses @fname and @sname to create the full name and then returns that. Of
course you can do things far more advanced than this with classes, but this
should give you something to start with.

HTH,
Sebastian
 
L

Lloyd Linklater

All the other guys said lots of cool and useful technical stuff. Let me
use history to give some of the ideology. In the procedural days,
programs became unmanagable when they got over 1/4 million lines or so,
though 1/2 million line programs were not unheard of.

Well, the notion of how to bunch things into blocks did for software
what the chip did for hardware. The software version of a chip is the
class. You make a class that has some characteristics foundational to
its descendants. You program in the things that cover all the basics.
Then, you add things as you get increasingly specific.

e.g. You want a class for dogs and cats. Well, they are fairly
different so what do they have in common?

class mammal
# stuff
end

class four_legged < mammal
# stuff
end

class cat < four_legged
# stuff
end

class dog < four_legged
# stuff
end

Note that if you add things in the base class, mammal in this case, it
trickles down to all descendants. This is VERY handy in many ways.

By coding this in pieces, you can more easily keep it all in your head
and, therefore, write far more complex programs with far more
simplicity. There are, of course, things that lend itself to art rather
than mere technique in class design, but writing classes so that they
are easily used is a good thing to know. Consider Ruby's approach. You
can do something.to_s all over the place. That takes planning. Not TOO
much planning, but some. That means that it had to be thought through
and included in all descendants.

So, classes makes life simpler when there is, in actuality, a good deal
more complexity behind the scenes.


p.s.
There are plenty of tutorials on this. The first one ask.com gave me is
http://java.sun.com/docs/books/tutorial/java/concepts/index.html
 
R

Rick DeNatale

There are plenty of tutorials on this. The first one ask.com gave me is
http://java.sun.com/docs/books/tutorial/java/concepts/index.html

I feel that I have to caution about trying to import concepts from
other languages directly to Ruby though.

Quoting from the java concepts document section "What is a Class?"

In the real world, you'll often find many individual objects all of
the same kind. There may be thousands of other bicycles in existence,
all of the same make and model. Each bicycle was built from the same
set of blueprints and therefore contains the same components. In
object-oriented terms, we say that your bicycle is an instance of the
class of objects known as bicycles. A class is the blueprint from
which individual objects are created.

This accurately describes Java classes, but Ruby classes really aren't
blueprints, at least not as I read the Java concept document.

In Java classes stamp out objects like cookie cutters, the cookie
cutter for the gingerbread class has a different shape from that of
the star class.

In Ruby, most classes use exactly the same cookie cutter which gives
the instance a few fields, like a klass pointer, and a pointer to a
hash where instance variables will be accumulated as methods get run
on the object.

To carry out the bicycle analogy a Ruby bicycle assembles itself as
you ride it, and it can magically acquire, say a bell, when you first
need to ring it.
 
R

Ron Fox

One way to think of a class (a restricted definition to get you started)
is as a data type and operations on that data type. Objects are
variables of that data type.

For example, consider a checking account. That has data
(a balance), and operations: deposit, withdraw, write_check,
balance etc.

You may have several bank accounts in a bank

class BankAccount
def initialize who account_number initial_balance
@name = who
@account_number = account_number
@balance = initial_balance
end

def deposit amount
@balance += amount
end

def withdraw amount
if amount <= @balance
@balance -= amount
else
raise overdraft
end
end
# and so on.
end

The class defines the data that makes up a checking account:
@name - Name of the person who owns the account.
@account_number - Account number of the account.
@balance - Money currently in the account.

initialize creates a new account (called when you do a BankAccount.new).
deposit deposits funds in the account
withdraw withdraws funds from the account.

Each object of type BankAccount has its own private copies of @name,
@account_number and @balance so:


rons_account = BankAccount.new("Ron, 12345, 100)
daves_account= BankAccount.new("Dave, 678, 150)

Create two objects of type bank account with very different values of
@name, @account_number and @balance.

rons_account.withdraw 10

Affects ron's copy of @balance but not dave's.

and so on.
 
J

jbrains762

I think of classes as a way to organize code that wants to share data,
and nothing more. Once you have three methods that need the same
parameter, consider moving them into a class and changing the
parameters into fields.

I'm jealous that you get to learn about classes without reading any of
the misguided theory on OOD. Have fun!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,999
Messages
2,570,243
Members
46,836
Latest member
login dogas

Latest Threads

Top