Tutorial: Classes and Objects in Ruby

Ruby is an object-oriented programming language, and everything in Ruby is an object.

Classes are blueprints for objects, defining their behavior and attributes. Objects are instances of classes.

What You’ll Learn

1. What Are Classes and Objects?

  • Class: A blueprint for creating objects. It defines methods and variables that the objects will have.
  • Object: An instance of a class.

Example

class Person
end

person = Person.new  # `person` is an object of the `Person` class.

2. Defining a Class

Syntax

class ClassName
  # Methods and variables
end

Example

class Person
  def greet
    puts "Hello, I am a person!"
  end
end

person = Person.new
person.greet  # Output: Hello, I am a person!

3. Creating Objects

Objects are created using the .new method.

Example

class Animal
  def speak
    puts "I am an animal!"
  end
end

dog = Animal.new
dog.speak  # Output: I am an animal!

4. Instance Variables and Methods

Instance variables store data unique to each object, prefixed with @.

Example

class Person
  def initialize(name, age)
    @name = name
    @age = age
  end

  def introduce
    puts "Hello, my name is #{@name} and I am #{@age} years old."
  end
end

person = Person.new("Alice", 30)
person.introduce
# Output: Hello, my name is Alice and I am 30 years old.

5. Class Variables and Methods

Class variables are shared among all instances of a class, prefixed with @@.

Class Variables

class Counter
  @@count = 0

  def initialize
    @@count += 1
  end

  def self.count
    @@count
  end
end

Counter.new
Counter.new
puts Counter.count  # Output: 2

Class Methods

Class methods are defined with self..

class MathHelper
  def self.square(number)
    number * number
  end
end

puts MathHelper.square(4)  # Output: 16

6. Accessors (attr_accessor, attr_reader, attr_writer)

Ruby provides shortcuts for defining getter and setter methods:

Accessor Description
attr_reader Creates getter methods
attr_writer Creates setter methods
attr_accessor Creates both getter and setter

Example

class Person
  attr_accessor :name, :age
end

person = Person.new
person.name = "Bob"
person.age = 25

puts person.name  # Output: Bob
puts person.age   # Output: 25

7. Inheritance

Inheritance allows a class to inherit methods and variables from another class.

Example

class Animal
  def speak
    puts "I can make sounds."
  end
end

class Dog < Animal
  def bark
    puts "Woof!"
  end
end

dog = Dog.new
dog.speak  # Output: I can make sounds.
dog.bark   # Output: Woof!

Overriding Methods

class Animal
  def speak
    puts "I am an animal."
  end
end

class Cat < Animal
  def speak
    puts "Meow!"
  end
end

cat = Cat.new
cat.speak  # Output: Meow!

8. Practical Examples

8.1 Bank Account Class

class BankAccount
  attr_reader :balance

  def initialize(owner, balance = 0)
    @owner = owner
    @balance = balance
  end

  def deposit(amount)
    @balance += amount
    puts "Deposited #{amount}. New balance: #{@balance}."
  end

  def withdraw(amount)
    if amount <= @balance
      @balance -= amount
      puts "Withdrew #{amount}. New balance: #{@balance}."
    else
      puts "Insufficient funds!"
    end
  end
end

account = BankAccount.new("Alice", 100)
account.deposit(50)      # Output: Deposited 50. New balance: 150.
account.withdraw(30)     # Output: Withdrew 30. New balance: 120.
account.withdraw(200)    # Output: Insufficient funds!

8.2 Shape Area Calculation

class Shape
  def area
    raise "Area method must be implemented by subclass"
  end
end

class Rectangle < Shape
  def initialize(width, height)
    @width = width
    @height = height
  end

  def area
    @width * @height
  end
end

class Circle < Shape
  def initialize(radius)
    @radius = radius
  end

  def area
    Math::PI * @radius**2
  end
end

rectangle = Rectangle.new(5, 10)
circle = Circle.new(7)

puts rectangle.area  # Output: 50
puts circle.area     # Output: 153.93804002589985

8.3 E-commerce System

class Product
  attr_accessor :name, :price

  def initialize(name, price)
    @name = name
    @price = price
  end

  def details
    "Product: #{@name}, Price: $#{@price}"
  end
end

class Cart
  def initialize
    @items = []
  end

  def add_product(product)
    @items << product
    puts "#{product.name} added to the cart."
  end

  def total_price
    @items.sum { |item| item.price }
  end
end

# Usage
product1 = Product.new("Laptop", 1200)
product2 = Product.new("Mouse", 25)

cart = Cart.new
cart.add_product(product1)
cart.add_product(product2)

puts "Total: $#{cart.total_price}"  # Output: Total: $1225

8.4 Polymorphism with Animals

class Animal
  def speak
    raise "This method must be implemented by subclass"
  end
end

class Dog < Animal
  def speak
    "Woof!"
  end
end

class Cat < Animal
  def speak
    "Meow!"
  end
end

animals = [Dog.new, Cat.new]
animals.each { |animal| puts animal.speak }
# Output:
# Woof!
# Meow!

9. Best Practices for Classes and Objects

  1. Encapsulation: Use instance variables to hide data and expose only necessary methods.
  2. Use Accessors: Use attr_accessor, attr_reader, and attr_writer for clean and concise code.
  3. DRY Principle: Use inheritance to avoid repeating code.
  4. Polymorphism: Use polymorphism to write flexible and reusable code.
  5. Avoid Overengineering: Keep classes simple and focused on a single responsibility.

10. Summary

Key Concepts

  • Classes define the blueprint for objects.
  • Instance variables store object-specific data.
  • Use attr_accessor, attr_reader, and attr_writer for cleaner code.
  • Inheritance allows classes to share behavior.

Examples in Context

Ruby classes and objects form the foundation of object-oriented programming, enabling you to build modular, reusable, and maintainable applications.

Related posts

Tutorial: Modules in Ruby

Tutorial: Blocks in Ruby

Tutorial: Methods in Ruby