English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Ruby Object-Oriented Programming

Ruby is a pure object-oriented language, where everything in Ruby appears in the form of an object. Every value in Ruby is an object, even the most primitive things: strings, numbers, and even true and false are objects. The class itself is also anobject, is Class A class example. This chapter will explain all the main features related to Ruby object-oriented programming.

A class is used to specify the form of an object, combining data representation and methods to organize data into a neat package. The data and methods in the class are called members of the class.

Ruby class definition

When you define a class, you are actually defining a blueprint for a data type. This does not define any data at all, but defines what the class name means, that is, defines what the objects of the class will consist of and what operations can be performed on the object.

Class definitions are terminated with the keyword class followed byclass name, and finally, start with a end to separate and indicate the end of the class definition. For example, we use the keyword class to define the Box class, as follows:

class Box
   code
end

By convention, the name must start with an uppercase letter, and if it contains multiple words, each word must start with an uppercase letter without any separators (e.g., CamelCase).

to define Ruby objects

The class provides the blueprint for objects, so in essence, objects are created based on the class. We use new Keywords are used to declare class objects. The following statements declare two objects of the class Box:

box1 = Box.new
box2 = Box.new

initialize method

initialize Method is a standard Ruby class method, which is the constructor of the class, similar to the initialize method in other object-oriented programming languages. constructor The work principle is similar. When you want to initialize some class variables at the same time as creating an object, the initialize method comes into play. This method takes a series of parameters, like other Ruby methods, and when using this method, it must be prefixed with def Keywords, as shown below:

class Box
   def initialize(w,h)
      @width, @height = w, h
   end
end

Example variable

Example variableInstance attributes, which become object properties when objects are created from the class. Each object's properties are assigned separately and do not share values with other objects. Inside the class, these properties are accessed using the @ operator, and outside the class, they are accessed using what is calledaccessor methodofPublicmethod to access. Below we use the class Box For example, take @width and @height as instance variables of the class Box.

class Box
   def initialize(w,h)
      # Assign value to example variable
      @width, @height = w, h
   end
end

Accesser (getter) & Setter (setter) method

To read class-defined variables from outside the class, we can define accessor (getter) methods to access. The following example demonstrates the usage of accessor methods:

Online Examples

#!/usr/bin/ruby -w
 
# Define class
class Box
   # Constructor
   def initialize(w,h)
      @width, @height = w, h
   end
 
   # Accessor methods
   def printWidth
      @width
   end
 
   def printHeight
      @height
   end
end
 
# Create object, initialize the height and width of the box
box = Box.new(10, 20)
 
# Use accessor methods
x = box.printWidth()
y = box.printHeight()
 
puts "Box width: #{x}"
puts "Box height: #{y}"

When the above code is executed, it will produce the following result:

Box width : 10
Box height : 20

Similar to the accessor method used to access variable values, Ruby provides a way to pass parameters into class-defined variables from outside the class, which is known asSetter method, defined as follows:

Online Examples

#!/usr/bin/ruby -w
 
# Define class
class Box
   # Constructor method
   def initialize(w,h)
      @width, @height = w, h
   end
 
   # Accessor methods
   def getWidth
      @width
   end
   def getHeight
      @height
   end
 
   # Setter methods
   def setWidth=(value)
      @width = value
   end
   def setHeight=(value)
      @height = value
   end
end
 
# Creating an object
box = Box.new(10, 20)
 
# Use setter method
box.setWidth = 30
box.setHeight = 50
 
# Use accessor methods
x = box.getWidth()
y = box.getHeight()
 
puts "Box width: #{x}"
puts "Box height: #{y}"

When the above code is executed, it will produce the following result:

Box width : 30
Box height : 50

Since both methods are very commonly used, Ruby defines attr_accessor :variable_name, attr_reader :variable_name, attr_writer :variable_name Three methods of attribute declaration. Among them:accessor = reader+writer.

At the same time, note that the variable name must be prefixed with : and separated by , between variable names.

instance method

instance methoddefinition is the same as other method definitions, both using def keywords, but they can only be used through class instances, as shown in the following example. Their functions are not limited to accessing instance variables, but can also perform other tasks as needed.

Online Examples

#!/usr/bin/ruby -w
 
# Define class
class Box
   # Constructor
   def initialize(w,h)
      @width, @height = w, h
   end
   # Example method
   def getArea
      @width * @height
   end
end
 
# Creating an object
box = Box.new(10, 20)
 
# Calling example method
a = box.getArea()
puts "Area of the box is: #{a}"

When the above code is executed, it will produce the following result:

Area of the box is: 200

Class method & class variable

Class variableare shared variables in all instances of the class. In other words, the class variable instances can be accessed by all object instances. Class variables are prefixed with two @ characters (@@), and class variables must be initialized within the class definition, as shown in the following example.

class methodsuse def self.methodname() Definition, class methods end with the delimiter end. Class methods can use classname.methodname Formal call, as shown in the following example:

Online Examples

#!/usr/bin/ruby -w
 
class Box
   # Initialize class variable
   @@count = 0
   def initialize(w,h)
      # Assign value to example variable
      @width, @height = w, h
 
      @@count += 1
   end
 
   def self.printCount()
      puts "Box count is: #@@count"
   end
end
 
# Create two objects
box1 = Box.new(10, 20)
box2 = Box.new(30, 100)
 
# Call a class method to output the box count
Box.printCount()

When the above code is executed, it will produce the following result:

Box count is: 2

to_s method

Every class you define has a to_s Example methods to return the string representation of an object. Below is a simple example representing the Box object based on width and height:

Online Examples

#!/usr/bin/ruby -w
 
class Box
   # Constructor method
   def initialize(w,h)
      @width, @height = w, h
   end
   # Define the to_s method
   def to_s
      "(w:#@width,h:#@height)" # Object string format
   end
end
 
# Creating an object
box = Box.new(10, 20)
 
# Automatically call the to_s method
puts "String representation of box is: #{box}"

When the above code is executed, it will produce the following result:

String representation of box is: (w:10,h:20)

Access Control

Ruby provides three levels of method protection, namely public, private, or protected. Ruby does not apply any access control to examples and class variables.

  • Public methods: Public methods can be called by any object. By default, methods are public, except that the initialize method is always private.

  • Private methods: Private methods cannot be accessed or viewed from outside the class. Only class methods can access private members.

  • Protected methods: Protected methods can only be called by objects of the class and its subclasses. Access is also restricted to the class and its subclasses.

Below is a simple example demonstrating the syntax of these three modifiers:

Online Examples

#!/usr/bin/ruby -w
 
# Define class
class Box
   # Constructor method
   def initialize(w,h)
      @width, @height = w, h
   end
 
   # Example methods are public by default
   def getArea
      getWidth() * getHeight
   end
 
   # Define private accessor methods
   def getWidth
      @width
   end
   def getHeight
      @height
   end
   # Make them private
   private :getWidth, :getHeight
 
   # Example method for outputting area
   def printArea
      @area = getWidth() * getHeight
      puts "Big box area is: #@area"
   end
   # Make the example method protected
   protected :printArea
end
 
# Creating an object
box = Box.new(10, 20)
 
# Calling example method
a = box.getArea()
puts "Area of the box is: #{a}"
 
# Attempt to call a protected example method
box.printArea()

When the above code is executed, it will produce the following results. In this case, the first method call is successful, but the second method will cause a problem.

Area of the box is: 200
test.rb:42: protected method `printArea' called for #
<Box:0xb7f11280 @height=20, @width=10(NoMethodError)

Class inheritance

inheritance, which is one of the most important concepts in object-oriented programming. Inheritance allows us to define a class based on another class, making it easier to create and maintain applications.

Inheritance helps with code reuse and fast execution, unfortunately, Ruby does not support multiple inheritance, but Ruby supports mixins.Mixin is a specific implementation of multiple inheritance, where only the interface part is inheritable.

When creating a class, the programmer can directly specify that the new class inherits from the members of an existing class, so that new data members and member functions do not need to be written from scratch. This existing class is calledbase class or superclass, the new class is calledDerived class or subclass.

Ruby also provides the concept of subclassing, which is inheritance. The following example explains this concept. The syntax to extend a class is very simple. Just add a < character and the name of the superclass to the class statement. For example, the following defines the class BigBox is Box The subclass of

Online Examples

#!/usr/bin/ruby -w
 
# Define class
class Box
   # Constructor method
   def initialize(w,h)
      @width, @height = w, h
   end
   # Example method
   def getArea
      @width * @height
   end
end
 
# Define subclass
class BigBox < Box
 
   # Add a new example method
   def printArea
      @area = @width * @height
      puts "Big box area is: #@area"
   end
end
 
# Creating an object
box = BigBox.new(10, 20)
 
# Output the area
box.printArea()

When the above code is executed, it will produce the following result:

Big box area is : 200

Method overloading

Although you can add new features in the derived class, sometimes you may want to change the behavior of methods already defined in the superclass. In this case, you can keep the method name unchanged and overload the functionality of the method, as shown in the following example:

Online Examples

#!/usr/bin/ruby -w
 
# Define class
class Box
   # Constructor method
   def initialize(w,h)
      @width, @height = w, h
   end
   # Example method
   def getArea
      @width * @height
   end
end
 
# Define subclass
class BigBox < Box
 
   # Modify the existing getArea method
   def getArea
      @area = @width * @height
      puts "Big box area is: #@area"
   end
end
 
# Creating an object
box = BigBox.new(10, 20)
 
# Output the area using overloaded method
box.getArea()

The following example is the output result of the run:

Big box area is : 200

operator overloading

We want to use + Operator to perform vector addition between two Box objects, using * Operator to multiply the width and height of Box, using unary operator - Reverse the width and height of Box. Here is a version of the Box class with defined mathematical operators:

class Box
  def initialize(w,h) # Initialize width and height
    @width, @height = w, h
  end
 
  def +(other) # Define + to perform vector addition
    Box.new(@width + other.width, @height + other.height)
  end
 
  def -# Define a unary operator - reverse the width and height
    Box.new(-@width, -@height)
  end
 
  def *(scalar) # Perform scalar multiplication
    Box.new(@width*scalar, @height*scalar)
  end
end

Freeze object

Sometimes, we want to prevent an object from being changed. In Object, the freeze method can achieve this, effectively turning an object into a constant. Any object can be frozen by calling Object.freeze to freeze. A frozen object cannot be modified, which means you cannot change its instance variables.

You can use Object.frozen? The method checks whether a given object has been frozen. If the object has been frozen, the method returns true, otherwise it returns a false value. The following example explains this concept:

Online Examples

#!/usr/bin/ruby -w
 
# Define class
class Box
   # Constructor method
   def initialize(w,h)
      @width, @height = w, h
   end
 
   # Accessor methods
   def getWidth
      @width
   end
   def getHeight
      @height
   end
 
   # Setter methods
   def setWidth=(value)
      @width = value
   end
   def setHeight=(value)
      @height = value
   end
end
 
# Creating an object
box = Box.new(10, 20)
 
# Let's freeze the object
box.freeze
if(box.frozen?)
   puts "Box object is a frozen object"
else
   puts "Box object is a normal object"
end
 
# Now try using setter methods
box.setWidth = 30
box.setHeight = 50
 
# Use accessor methods
x = box.getWidth()
y = box.getHeight()
 
puts "Width of the box is: #{x}"
puts "Height of the box is: #{y}"

When the above code is executed, it will produce the following result:

Box object is a frozen object
test.rb:20:in `setWidth=': can't modify frozen object (TypeError)
        from test.rb:39

Class Constant

You can define a constant within the class by assigning a direct numeric or string value to a variable. The definition of a constant does not require the use of @ or @@. By convention, the names of constants are written in uppercase.

Once a constant is defined, you cannot change its value. You can access the constant directly within the class, just like a variable, but if you want to access the constant outside the class, you must use classname::constantas shown in the following example.

Online Examples

#!/usr/bin/ruby -w
 
# Define class
class Box
   BOX_COMPANY = "TATA Inc"
   BOXWEIGHT = 10
   # Constructor method
   def initialize(w,h)
      @width, @height = w, h
   end
   # Example method
   def getArea
      @width * @height
   end
end
 
# Creating an object
box = Box.new(10, 20)
 
# Calling example method
a = box.getArea()
puts "Area of the box is: #{a}"
puts Box::BOX_COMPANY
puts "Box weight is: #{Box::BOXWEIGHT}"

When the above code is executed, it will produce the following result:

Area of the box is: 200
TATA Inc
Box weight is: 10

Class constants can be inherited and can also be overloaded like example methods.

Using allocate to create an object

There may be a situation where you want to create an object without calling the object constructor initialize In the case of creating an object, that is, using the new method to create an object, in this case, you can call allocate to create an uninitialized object, as shown in the following example:

Online Examples

#!/usr/bin/ruby -w
 
# Define class
class Box
   attr_accessor :width, :height
 
   # Constructor method
   def initialize(w,h)
      @width, @height = w, h
   end
 
   # Example method
   def getArea
      @width * @height
   end
end
 
# Using new to create an object
box1 = Box.new(10, 20)
 
# Using allocate to create another object
box2 = Box.allocate
 
# Using box1 Calling example method
a = box1.getArea()
puts "Area of the box is: #{a}"
 
# Using box2 Calling example method
a = box2.getArea()
puts "Area of the box is: #{a}"

When the above code is executed, it will produce the following result:

Area of the box is: 200
test.rb:14: warning: instance variable @width not initialized
test.rb:14: warning: instance variable @height not initialized
test.rb:14:in `getArea': undefined method `*" 
   for nil:NilClass (NoMethodError) from test.rb:29

Class Information

Ruby's self and Java's this have similarities, but they are also quite different. Java methods always refer to the current object in the example method, so this usually points to the current object. However, Ruby code is executed line by line, so self has different meanings in different contexts. Let's take a look at the following example:.

Online Examples

#!/usr/bin/ruby -w
 
class Box
   # Output class information
   puts "Class of self = #{self.class}"
   puts "Name of self = #{self.name}"
end

When the above code is executed, it will produce the following result:

Class of self = Class
Name of self = Box

This means that the class definition can be executed by treating the class as the current object, which also means that the method in the metaclass and superclass is available during the execution of the method definition.