Ruby Object-Oriented (above)
Ruby Object-Oriented (top)
Ruby is a purely object-oriented language. everything in Ruby is an object. every value in Ruby is an object, even the most primitive things: numbers, strings, even true and false. A class itself is also an object, an instance of the Class class. This chapter explains all the major features associated with Ruby's object orientation.
Classes are used to specify the form of an object, which combines data representations and methods to organize data into a neat package. The data and methods in a class are called class members.
Ruby Class Definitions
When you define a class, you are actually defining a blueprint for a data type. This doesn't actually define any data, but rather defines what the name of the class means, that is, it defines what the objects of the class will consist of and what operations can be performed on that object.
A class definition begins with the keyword class, followed by the class name, and terminated by a end. For example, we use the keyword class to define the Box class, as shown below:
1. class Box
2. code
3. end
By convention, names must start with a capital letter, or if they contain more than one word, the first letter of each word is capitalized, but there is no separator (e.g., CamelCase).
Defining Ruby Objects
Classes provide the blueprint for objects, so basically, objects are created based on classes. We use the new keyword to declare objects of a class. The following statement declares two objects of class Box:
2. box2 = Box.new
The *## initialize method
The initialize method is a standard Ruby class method, a class constructor, similar to how constructor works in other object-oriented programming languages. The initialize method is useful when you want to initialize some class variables at the same time you create an object. This method takes a number of arguments and, like other Ruby methods, must be preceded by the def keyword, as shown below:
2. def initialize(w,h)
3. @width, @height = w, h
4. end
5. end
Instance variables
Instance variables are class attributes that become properties of an object when the object is created using the class. Each object's attributes are assigned values individually and do not share values with other objects. Inside the class, these attributes are accessed using the @ operator, and outside the class, they are accessed using public methods called accessor methods. In the following, we take the class Box defined above and use @width and @height as instance variables of the class Box.
2. def initialize(w,h)
3. # Assign values to the instance variables.
4. @width, @height = w, h
5. end
6. end
Accessor & Setter Methods
In order to read the variables defined in a class from outside the class, we can access them by defining getter methods. The following example demonstrates the usage of accessor methods:
Example
1. #!/usr/bin/[[ruby](/search?q=ruby)](/search?q=ruby) -w
2.
3. # Define the class
4. class Box
5. # Constructor
6. def initialize(w,h)
7. @width, @height = w, h
8. end
9.
10. # Accessor methods
11. def printWidth
12. @width
13. end
14.
15. def printHeight
16. @height
17. end
18. end
19.
20. # Create the object and initialize the height and width of the box.
21. box = Box.new(10, 20)
22.
23. # Use the accessor methods
24. x = box.printWidth()
25. y = box.printHeight()
26.
27. puts "box width : #{x}"
28. puts "box height : #{y}"
When the above code is executed, it produces the following result:
1. box width : 10
2. Box height : 20
Similar to the accessor methods used to access the value of a variable, Ruby provides a way to pass parameters outside of a class into a variable already defined in the class, known as a setter method , defined as follows:
Example
1. #!/usr/bin/ruby -w
2.
3. # Define the class
4. class Box
5. # Constructor methods
6. def initialize(w,h)
7. @width, @height = w, h
8. end
9.
10. # Accessor methods
11. def getWidth
12. @width
13. end
14. def getHeight
15. @height
16. end
17.
18. # Setter methods
19. def setWidth=(value)
20. @width = value
21. end
22. def setHeight=(value)
23. @height = value
24. end
25. end
26.
27. # Create the object
28. box = Box.new(10, 20)
29.
30. # Use the setter method
31. box.setWidth = 30
32. box.setHeight = 50
33.
34. # Use the accessor method
35. x = box.getWidth()
36. y = box.getHeight()
37.
38. puts "boxWidth : #{x}"
39. puts "boxHeight : #{y}"
When the above code is executed, it produces the following result:
1. Box width : 30
2. Box height : 50
Since the two methods are very commonly used, Ruby defines three methods for declaring attributes, attr_accessor :variable_name, attr_reader :variable_name, attr_writer :variable_name. Where accessor=reader+writer .
Also note that variable names must be preceded by : and separated by ,.
Instance methods
Instance methods are defined using the def keyword like any other method, but they can only be used through class instances, as shown in the example below. Their functionality is not limited to accessing instance variables, but can also do as many other tasks as you need.
Instance
1. #!/usr/bin/ruby -w
2.
3. # Define the class
4. class Box
5. # Constructor
6. def initialize(w,h)
7. @width, @height = w, h
8. end
9. # Instance methods
10. def getArea
11. @width * @height
12. end
13. end
14.
15. # Create the object
16. box = Box.new(10, 20)
17.
18. # Call the instance method
19. a = box.getArea()
20. puts "Area of the box is : #{a}"
When the above code is executed, it produces the following result:
Area of the box is : 200
Class Methods & Class Variables
Class variables are variables that are shared among all instances of a class. In other words, an instance of a class variable can be accessed by all object instances. Class variables are prefixed with two @ characters (@@) and class variables must be initialized in the class definition as shown in the following example.
Class methods are defined using def self.methodname() and are terminated with an end separator. Class methods can be invoked using the form classname.methodname with the class name, as shown in the following example:
Example
1. #!/usr/bin/ruby -w
2.
3. class Box
4. # Initialize class variables
5. @@count = 0
6. def initialize(w,h)
7. # Assign values to instance variables
8. @width, @height = w, h
9.
10. @@count += 1
11. end
12.
13. def self.printCount()
14. puts "Box count is : #@@count"
15. end
16. end
17.
18. # Create two objects
19. box1 = Box.new(10, 20)
20. box2 = Box.new(30, 100)
21.
22. # Call the class method to output the box count
23. box.printCount()
When the above code is executed, it produces the following result:
Box count is : 2
to_s method
Any class you define has a to_s instance method that returns a string representation of the object. Here's a simple example that represents a Box object by its width and height:
Instance
2.
3. class Box
4. # Constructor methods
5. def initialize(w,h)
6. @width, @height = w, h
7. end
8. # Define the to_s method
9. def to_s
10. "(w:#@width,h:#@height)" # Format the object as a string.
11. end
12. end
13.
14. # Create the object
15. box = Box.new(10, 20)
16.
17. # Automatically call the to_s method
18. puts "String representation of box is : #{box}"
When the above code is executed, it produces the following result:
String representation of box is : (w:10,h:20)
Access control
Ruby provides you with three levels of instance method protection, public, private, or protected Ruby does not apply any access control to instances and class variables.
- Private methods: Private methods cannot be accessed or viewed from outside the class. Only class methods can access private members.
- Public methods: Public methods can be called by any object. By default, methods are public, except for the initialize method, which is always private.
- Protected methods: Protected methods can only be called by objects of the class and its subclasses. Access is also restricted to within the class and its subclasses.
The following is a simple example that demonstrates the syntax of these three modifiers:
Example
2.
3. # Define the class
4. class Box
5. # Constructor methods
6. def initialize(w,h)
7. @width, @height = w, h
8. end
9.
10. # Instance methods are public by default
11. def getArea
12. getWidth() * getHeight
13. end
14. 15.
15. # Define the private accessor method
16. def getWidth
17. @width
18. end
19. def getHeight
20. @height
21. end
22. # make them private
23. private :getWidth, :getHeight
24.
25. # Instance method for outputting area
26. def printArea
27. @area = getWidth() * getHeight
28. puts "Big box area is : #@area"
29. end
30. # Make the instance method protected
31. protected :printArea
32. end
33. end
34. # Create the object
35. box = Box.new(10, 20)
36.
37. # Call the instance method
38. a = box.getArea()
39. puts "Area of the box is : #{a}"
40. 41.
41. # Try to call the protected instance method
42. box.printArea()
When the above code executes, it produces the following results. Here, the first method call succeeds but the second method creates a problem.
2. test.rb:42: protected method `printArea' called for #
3. <Box:0xb7f11280 @height=20, @width=10> (NoMethodError)