In this chapter, you will learn to create classes and objects. Let's start with the simplest thing that we can do with class.
class Square end
class is a keyword in Ruby. It is used to define a class. We write class ClassName to create a class having the name 'ClassName'. So in the above example, the name of the class is Square.
In short, class Square means that Square is a class.
We terminate the body of a class also by using end.
Creating objects of class
class Square end a = Square.new() b = Square.new()
Here, 'a' and 'b' are objects of the Square class. An object is made by writing ObjectName = ClassName.new(). new keyword creates a new object of the Square class.
a = Square.new() : This means that 'a' is an object of the Square class.
Methods inside class
As discussed in the previous chapter, we can have methods ( or functions ) in a class. Let's see an example.
class Square def m1 @about = "I am a Square" puts @about puts "I am in method m1" end end a = Square.new() a.m1
I am in method m1
Here, m1 is a method inside the Square class. 'about' is an instance variable. As told in the previous chapter, we use @ for an instance variable.
a = Square.new() : We have made a new object of the Square class.
a.m1 : We access a method of a class using . ( dot ). For an instance method, we first write the name of the object and then the name of the method. So by writing a.m1, we are accessing the method 'm1' for the object 'a'.
After the method 'm1' has been called, the codes inside its body are executed.
@about = "I am Square" : 'about' is an instance variable because '@' is used before it.
I think that you have not understood instance variable very clearly. Don't worry, you will understand it in the next section i.e. 'Class with constructor'.
Class having constructor
Suppose, we have to make a 'Student' class. Student must have a name. So, it would be nice if we give the name of the student while making its object. This is what we can do with constructors. Constructor is a special method having a name 'initialize' which runs while creating an object. Let's see how we do this.
class Student def initialize(n) @name = n end def print_name puts @name end end a = Student.new("Sam") a.print_name
Here, we have a method having name 'initialize' and it is the constructor.
a = Student.new("Sam") : We have made an object 'a' of the 'Student' class and while making it, we have passed a string "Sam".
Now you know that after making an object, the constructor of the class 'Student' will run and this string "Sam" will be passed as a parameter to the constructor. So, this string "Sam" will be passed as a parameter to the method 'initialize(n)' and 'n' will become the passed string "Sam" as discussed in the 'function chapter'.
In the constructor ( method having name 'initialize' ), we have, @name = n. So, a variable 'name' will be assigned the value that we have passed during the creation of the object.
Now, we know that 'name' is an instance variable ( as @ is used ). We also know that instance variable is different for different objects. So, the value of the variable 'name' for our object 'a' is "Sam" and it will be different for different objects. In short, it means that the 'name' of 'a' is 'Sam'.
Now I hope it is clear. Let's see one more example to make it clearer.
class Square def initialize(side) @side = side end def get_area return @side*@side end def get_perimeter return 4*@side end end a = Square.new(4) b = Square.new(16) puts a.get_area puts b.get_perimeter
@side = side : Here, @side represents the instance variable 'size' of the objects of the class 'Square' and side on the right side is the side which was passed to 'initialize(size)' ( while making objects ). '@side' is an instance variable and that is why it is different for different objects of the class ( 4 for 'a' and 16 for 'b' ). Rest of the part should be clear.
Class variable and class method
As discussed in the last chapter, a class variable is a variable which is common and same to every object of the class and is defined for a class. We use @@ to define and use a class variable.
Same as a class variable, class method is also defined for a class and is same to every object of the class. We define a class method by writing self.MethodName(). And we call it on the class and not on the object. E.g.- if sq is some method of a Square class, then it will be called on Square (Square.sq) and not on its objects.
Have a look at the following example.
class Square #class variable @@object_count = 0 def initialize(side) @side = side @@object_count = @@object_count+1 end def get_area return @side*@side end def get_perimeter return 4*@side end #class method def self.no_of_object print @@object_count end end a = Square.new(4) b = Square.new(16) puts a.get_area puts b.get_perimeter #calling class method puts Square.no_of_object
In the above example, 'object_count' is a class variable ( @@ is used ) to count the number of objects of the Square class. Also, 'no_of_object' is a class method ( self.no_of_object is used while defining ) to print the number of objects. One more thing you should notice here is that 'no_of_object' is called on Square ( class ) and not on its objects.
Use of freeze and frozen?
Sometimes, we want to prevent an object from being changed. This is achieved by freeze. We use frozen? to check whether an object is frozen or not. Let's see an example on this.
class Square def initialize(side) @side = side end def set_side(s) @side = s end end a = Square.new(4) b = Square.new(16) a.freeze b.set_side(5) puts a.frozen? puts b.frozen? a.set_side(5)
a.rb:8:in `set_side': can't modify frozen Square (RuntimeError)
from a.rb:18:in `<main>'
You can see that we got an error when we tried to modify the frozen object 'a'.
Constant in class
Unlike variables, we can't change the value of a constant in our program. We can access a constant directly inside a class and to access a constant outside of the class, we use ClassName::CONSTANT. It is a convention to keep the name of the constant in upper case. Let's see the following example:
class Circle #defining a constant PI = 3.14 def get_area(radius) return PI*radius*radius end end a = Circle.new() puts a.get_area(4) puts Circle::PI
'PI' is a constant in the above example, so we can't change its value. You can see that we have accessed it inside the class directly and outside the class, we used :: with the name of the class.
Programming is a skill best acquired by practice and example rather than from books.