Learnerslesson
   JAVA   
  SPRING  
  SPRINGBOOT  
 HIBERNATE 
  HADOOP  
   HIVE   
   ALGORITHMS   
   PYTHON   
   GO   
   KOTLIN   
   C#   
   RUBY   
   C++   




RUBY - CLASS AND OBJECT


Anything and everthing you see around, can be said to be a class. Be it a Car or a Tree or even a Human.


A class can be described as a blueprint which says how an object is going to behave once it is created. And a class has a behaviour and a state.


Let us simplify with the below example.


As we all know, we being Humans, have a common behavior of speaking and eating.


Now, just imagine, when God had created the Human Beings, God had prepared a blue print stating, all Humans will have a common behavior of speaking and eating.

java_Collections

So, speaking and eating behaviour would be common in all Human Beings. But each Human Being will have a property, that would makes them unique.


i.e. Say, a guy named John who speaks English and eats Burger is one Person. And a girl named Rakhi who speaks Hindi and eats Rice is a different Person.


So, let's say, God had also made this rule called along with the Behaviour, a Human Being should also have property/state(i.e. Name, language, food) that will make them unique.

java_Collections

Now, if we compare the above Human as a class. The name, food and language are called as property/state that will be unique for a Human Being.


And the Eat and Speak are behaviour that will be common to all Human Beings.


Now, let us create two humans out of the above class. i.e. A guy named John who speaks English and eats Burger and a girl named Rakhi who speaks Hindi and eats Rice.

java_Collections

So, Human is a Class that is just a Blue print and doesn't exist physically.


And human1 and human2 are called as Objects that exist physically (i.e. The John and Rakhi are humans that have physical existence) and are derived from the above class Human.


Now, let us see, how can we implement Classes and Objects in Ruby.


Example :



class Human

  	def get_name
    	@name
  	end

  	def set_name(name)
    	@name = name
  	end
  
    def get_food
    	@food
  	end

  	def set_food(food)
    	@food = food
  	end
  
    def get_language
    	@language
  	end

  	def set_language(language)
    	@language = language
  	end
  	
	def eat()
		puts "#{@name} eats #{@food}"
	end	

	def speak()
		puts "#{@name} speaks #{@language}"
	end	
		
end		


human1 = Human.new()
human1.set_name("John")
human1.set_food("Burger")
human1.set_language("English")

human2 = Human.new()
human2.set_name("Rakhi")
human2.set_food("Rice")
human2.set_language("Hindi")


human1.eat()
human1.speak()

human2.eat()
human2.speak()


Output :



  John eats Burger
  John speaks English
  Rakhi eats Rice
  Rakhi speaks Hindi

Creating a class


So, in the above example, we have created a class named Human.


class Human

The syntax of declaring a class is quite simple, class name(i.e. Human) followed by the keyword class.

java_Collections

And as we have seen know humans have a common behavior of speaking and eating.


And the behaviours in Ruby can be represented by Methods


And next we have the eat(...) behaviour/Method.


def eat()
	puts "#{@name} eats #{@food}"
end

And in the print statement we have the properties/state name and food(Detail explanation later).


Similarly, we have the speak(...) behaviour/method.


def speak()
	puts "#{@name} speaks #{@language}"
end

Now, all over the above class(Be it the speak() method or the eat() method). The name, food and language, have a prefix @.


That is because a variable that begins with @ are called instance variables(Which we will understand shortly).


Now, we have created the class Human.

java_Collections

Now, just remember, a class has no existence of its own. It only comes to effect once an Object is created out of it.


And we will see next, how can we create an Object of Human class.


Creating an object of the Human class


human1 = Human.new()

Creating an object is also pretty straight forward. You give an object name, human1 and initialise with the class name following the new opoerator.

java_Collections

So, human1 object is created. And human1 object is for the guy named John who speaks English and eats Burger.


Now, we come to the million dollar question. How do we assign the values John, English and Burger, to the attributes name, food and language?


And Ruby provides getter and setter method for that.


Getters and Setters to initialise values to the objects


Setter Method


The Setter method is used to set or assign values to an attribute(i.e. name or language) of a class.


So, when we try to assign the values John, English and Burger, to the attributes name, food and language.


We call the setter methods and they does the task.


Let us see how we have initialised the value John to name.


human1.set_name("John")

So, we have used the Object name (i.e. human1) and called the setter method for name and passing John to the setter method(i.e. set_name("John"))


And the Setter Method for name gets called.


def set_name(name)
	@name = name
end

Assigning the value John to name.

java_Collections

And a local variable name is created with the value John,

java_Collections

Then the value John is taken from the local variable name and initialises to the actual attribute name.


@name = name
java_Collections


Now, does it ring a bell! Why the name has @ before it?


@name = name

name is just an ordinary variable and @name is the attribute of the human1 object.


Similarly, all the other values are initialised using the setter methods.

java_Collections

Similarly, we have created human2 object that contains the details of a girl Rakhi who speaks Hindi and eats Rice.


human2 = Human.new()
human2.set_name("Rakhi")
human2.set_food("Rice")
human2.set_language("Hindi")
java_Collections


Getter Method


And the Getter method is used to get the values of an attribute(i.e. name or language) in a class.


def get_name
	@name
end

The idea behind Getter method is, an attribute of a class should not be accessed directly outside the class.


It should always be accessed with a method that belongs to the class.


In this example, we haven't called the Getter methods because we have two other methods that helps us get the attributes, name, food and language.


The methods are, eat() and speak().


human1.eat()

So, the eat() method of human1 object is called.


def eat()
	puts "#{@name} eats #{@food}"
end

And the print statement,


	puts "#{@name} eats #{@food}"

Goes to the human1 object and finds that, @name is John (Since, self is referring to the human1 object now) and @food is referring to Burger.


So we get the output,


Rakhi eats Rice

And exactly same logic applies to the other lines as well.


human1.eat()
human1.speak()

human2.eat()
human2.speak()

So far, we have seen that we have created two objects human1 and human2 from Human class that contains the details of two people, John and Rakhi.

java_Collections

Now, if you see the Human class, it has three attributes name, food and language that changes for each object.


i.e. The name, food and language has different values for the objects human1 and human2.


What if, you want an attribute of a class that has same values for all the objects. Let us clear with the below example.


Just imagine, all the objects of the Human class would be Human Beings. Let's say, we add one more attribute to the Human class i.e. type.


And the value of type attribute would be same for all the objects of Human class.


And all we need to do is declare the type with @@ (i.e. @@type).


Declaring an attribute with '@@'


So, when we declare an attribute with @@, it becomes a class variable. i.e. Its value remains same for all the objects.


Example :



class Human

	@@type = "Human Being"

  	def get_name
    	@name
  	end

  	def set_name(name)
    	@name = name
  	end
  
    def get_food
    	@food
  	end

  	def set_food(food)
    	@food = food
  	end
  
    def get_language
    	@language
  	end

  	def set_language(language)
    	@language = language
  	end
  	
	def eat()
		puts "#{@name} eats #{@food} and is a #{@@type}"
	end	

	def speak()
		puts "#{@name} speaks #{@language}"
	end	
		
end		


human1 = Human.new()
human1.set_name("John")
human1.set_food("Burger")
human1.set_language("English")


human2 = Human.new()
human2.set_name("Rakhi")
human2.set_food("Rice")
human2.set_language("Hindi")


human1.eat()
human1.speak()

human2.eat()
human2.speak()


Output :



  John eats Burger and is a Human Being
  John speaks English
  Rakhi eats Rice and is a Human Being
  Rakhi speaks Hindi

So, we have modified the above example by adding a class variable @@type and assigned the value Human Being to it.


@@type = "Human Being"

So, when we create two objects human1 and human2.


human1 = Human.new()
human1.set_name("John")
human1.set_food("Burger")
human1.set_language("English")

human2 = Human.new()
human2.set_name("Rakhi")
human2.set_food("Rice")
human2.set_language("Hindi")

The attribute @@type becomes a part of human1 and human2.

java_Collections

Now, when we call the eat() method from human1 and human2,


human1.eat()
human2.eat()

The eat() method gets called.


def eat()
	puts "#{@name} eats #{@food} and is a #{@@type}"
end

And the print statement,


puts "#{@name} eats #{@food} and is a #{@@type}"

Prints different values for name and food. But for type, same value is printed for both objects.


John eats Burger and is a Human Being
Rakhi eats Rice and is a Human Being