🏗️ Módulo 7-8: Programación Orientada a Objetos (Básica)

Duración: Semanas 7 y 8

Objetivos del Módulo

  • Entender los conceptos fundamentales de la POO
  • Aprender a crear y usar clases y objetos
  • Dominar atributos, métodos de instancia y de clase
  • Practicar encapsulación y abstracción

Contenido Teórico

1. ¿Qué es la Programación Orientada a Objetos?

La POO es un paradigma de programación que organiza el código en “objetos” - entidades que combinan datos (atributos) y comportamientos (métodos).

Conceptos clave:

  • Clase: Plantilla o molde para crear objetos
  • Objeto: Instancia de una clase
  • Atributo: Característica o propiedad del objeto
  • Método: Acción que puede realizar el objeto

2. Definir una Clase Básica

class Person
  def initialize(name, age)
    @name = name  # Variable de instancia
    @age = age
  end
  
  def greet
    "Hola, soy #{@name} y tengo #{@age} años"
  end
  
  def have_birthday
    @age += 1
    "¡Feliz cumpleaños! Ahora tengo #{@age} años"
  end
end

# Crear objetos (instancias)
person1 = Person.new("Ana", 25)
person2 = Person.new("Luis", 30)

puts person1.greet
puts person2.have_birthday

3. Atributos: attr_reader, attr_writer, attr_accessor

class Product
  # Solo lectura
  attr_reader :id, :name
  
  # Solo escritura
  attr_writer :price
  
  # Lectura y escritura
  attr_accessor :category, :stock
  
  def initialize(id, name, price)
    @id = id
    @name = name
    @price = price
    @category = "Sin categoría"
    @stock = 0
  end
  
  def price
    @price
  end
  
  def price_with_tax
    @price * 1.21
  end
end

product = Product.new(1, "Laptop", 999.99)
puts product.name        # Solo lectura
product.category = "Tecnología"  # Lectura y escritura
product.price = 899.99    # Solo escritura

4. Métodos de Clase vs Métodos de Instancia

class Counter
  @@total_counters = 0  # Variable de clase
  
  def initialize(initial_value = 0)
    @value = initial_value
    @@total_counters += 1
  end
  
  # Método de instancia
  def increment
    @value += 1
  end
  
  def value
    @value
  end
  
  # Método de clase
  def self.total_counters
    @@total_counters
  end
  
  def self.reset_global
    @@total_counters = 0
  end
end

counter1 = Counter.new(5)
counter2 = Counter.new(10)

puts counter1.value              # 5
puts Counter.total_counters    # 2

5. Encapsulación y Métodos Privados

class BankAccount
  attr_reader :account_number, :holder
  
  def initialize(account_number, holder, initial_balance = 0)
    @account_number = account_number
    @holder = holder
    @balance = initial_balance
  end
  
  def check_balance
    @balance
  end
  
  def deposit(amount)
    if amount > 0
      @balance += amount
      "Depósito exitoso. Nuevo saldo: #{@balance}"
    else
      "La cantidad debe ser positiva"
    end
  end
  
  def withdraw(amount)
    if amount > 0 && amount <= @balance
      @balance -= amount
      "Retiro exitoso. Nuevo saldo: #{@balance}"
    else
      "Fondos insuficientes o cantidad inválida"
    end
  end
  
  private
  
  def validate_amount(amount)
    amount > 0
  end
end

6. Constantes en Clases

class Calculator
  PI = 3.14159
  E = 2.71828
  
  def self.circle_area(radius)
    PI * radius ** 2
  end
  
  def self.circumference(radius)
    2 * PI * radius
  end
end

puts Calculator::PI
puts Calculator.circle_area(5)

7. Ejemplo Completo: Sistema de Biblioteca

class Book
  attr_reader :isbn, :title, :author
  attr_accessor :available
  
  def initialize(isbn, title, author)
    @isbn = isbn
    @title = title
    @author = author
    @available = true
  end
  
  def to_s
    "#{@title} por #{@author} (ISBN: #{@isbn})"
  end
  
  def lend
    if @available
      @available = false
      "Libro prestado exitosamente"
    else
      "El libro no está disponible"
    end
  end
  
  def return_book
    @available = true
    "Libro devuelto exitosamente"
  end
end

class Library
  def initialize(name)
    @name = name
    @books = []
  end
  
  def add_book(book)
    @books << book
    "Libro agregado a la biblioteca"
  end
  
  def search_by_title(title)
    @books.select { |book| book.title.downcase.include?(title.downcase) }
  end
  
  def available_books
    @books.select { |book| book.available }
  end
  
  def total_books
    @books.length
  end
end

Ejercicios Prácticos

Ve al archivo ejercicios.rb para practicar los conceptos aprendidos.

Proyecto del Módulo

Ve al archivo proyecto_tienda_online.rb para completar el proyecto de este módulo.