Programacion Orientada a Objetos
## Objetivos de Aprendizaje
- Crear clases y objetos
- Implementar herencia
- Usar modulos como mixins
- Controlar el acceso a metodos
## Clases
### Definir una Clase
```ruby
class Perro
# Initialize es el constructor
def initialize(nombre, raza)
@nombre = nombre # Variable de instancia
@raza = raza
end
# Metodo de instancia
def ladrar
"#{@nombre} dice Guau!"
end
# Getter
def nombre
@nombre
end
# Setter
def nombre=(valor)
@nombre = valor
end
end
# Crear objeto
perro = Perro.new("Buddy", "Golden Retriever")
puts perro.ladrar # "Buddy dice Guau!"
```
### Metodos de Atributos
```ruby
class Perro
attr_reader :nombre # Solo lectura
attr_writer :nombre # Solo escritura
attr_accessor :raza # Lectura y escritura
def initialize(nombre, raza)
@nombre = nombre
@raza = raza
end
end
perro = Perro.new("Buddy", "Golden Retriever")
puts perro.nombre # "Buddy"
perro.nombre = "Max"
puts perro.nombre # "Max"
```
### Palabra Clave Self
```ruby
class Contador
@@conteo = 0
def initialize
@@conteo += 1
end
def self.total
@@conteo
end
def id_instancia
self.object_id
end
def incrementar
self.class.incrementar_conteo
end
private
def self.incrementar_conteo
@@conteo += 1
end
end
```
## Variables de Instancia vs de Clase
```ruby
class CuentaBancaria
@@tasa_interes = 0.05 # Variable de clase (compartida)
def initialize(saldo)
@saldo = saldo # Variable de instancia (por objeto)
end
def interes
@saldo * @@tasa_interes
end
end
```
## Metodos
### Publico, Privado, Protegido
```ruby
class Usuario
def metodo_publico
"Puedo ser llamado desde cualquier lugar"
end
private
def metodo_privado
"Solo puedo ser llamado internamente"
end
protected
def metodo_protegido
"Puedo ser llamado por otras instancias de la misma clase"
end
end
```
### Privado con Argumentos
```ruby
class Calculadora
def operaciones(a, b)
sumar(a, b) + restar(a, b)
end
private
def sumar(a, b)
a + b
end
def restar(a, b)
a - b
end
end
```
## Herencia
### Herencia Basica
```ruby
class Animal
def initialize(nombre)
@nombre = nombre
end
def hablar
"..."
end
end
class Perro < Animal
def hablar
"Guau!"
end
end
class Gato < Animal
def hablar
"Miau!"
end
end
perro = Perro.new("Buddy")
puts perro.hablar # "Guau!"
```
### Super
```ruby
class Vehiculo
def initialize(marca, modelo)
@marca = marca
@modelo = modelo
end
def info
"#{@marca} #{@modelo}"
end
end
class Auto < Vehiculo
def initialize(marca, modelo, ano)
super(marca, modelo) # Llamar al initialize padre
@ano = ano
end
def info
"#{super} (#{@ano})"
end
end
```
### Clases Abstractas
Ruby no tiene clases abstractas de forma nativa, pero puedes simularlas:
```ruby
class ClaseAbstracta
def initialize
raise NotImplementedError, "La subclase debe implementar"
end
end
```
## Modulos
### Como Espacio de Nombres
```ruby
module UtilidadesMatematicas
class Calculadora
def sumar(a, b)
a + b
end
end
end
calc = UtilidadesMatematicas::Calculadora.new
puts calc.sumar(2, 3)
```
### Como Mixin
```ruby
module Caminable
def caminar
"#{nombre} esta caminando"
end
end
class Persona
include Caminable
def initialize(nombre)
@nombre = nombre
end
attr_reader :nombre
end
persona = Persona.new("Alicia")
puts persona.caminar
```
### Multiples Mixins
```ruby
module Volador
def volar
"#{nombre} esta volando"
end
end
module Nadador
def nadar
"#{nombre} esta nadando"
end
end
class Pato
include Volador
include Nadador
def initialize(nombre)
@nombre = nombre
end
attr_reader :nombre
end
pato = Pato.new("Donald")
puts pato.volar
puts pato.nadar
```
### Metodos de Modulo
```ruby
module Configuracion
@depuracion = false
def self.depuracion
@depuracion
end
def self.depuracion=(valor)
@depuracion = valor
end
# Sintaxis alternativa
class << self
attr_accessor :depuracion
end
end
Configuracion.depuracion = true
puts Configuracion.depuracion
```
## Ciclo de Vida del Objeto
```ruby
class Ejemplo
puts "Definicion de clase cargada"
def initialize
puts "Objeto creado"
end
def finalizar
puts "Objeto a punto de ser recolectado"
end
end
# Nota: Ruby no tiene destructores,
# usa at_exit o ObjectSpace para limpieza
```
## Duck Typing
Ruby usa duck typing - si camina como un pato...
```ruby
class Pato
def graznar
"Cuac!"
end
end
class Persona
def graznar
"Estoy fingiendo ser un pato"
end
end
def hacer_cuac(pato)
puts pato.graznar
end
hacer_cuac(Pato.new) # "Cuac!"
hacer_cuac(Persona.new) # "Estoy fingiendo ser un pato"
```
## Constantes en Clases
```ruby
class Matematicas
PI = 3.14159
E = 2.71828
class << self
attr_reader :version
end
end
puts Matematicas::PI # 3.14159
```
## Metodos de Clase vs Metodos de Instancia
```ruby
class Ejemplo
# Metodo de instancia
def metodo_instancia
"Llamado en instancia"
end
# Metodo de clase (self.metodo)
def self.metodo_clase
"Llamado en clase"
end
# Sintaxis alternativa de metodo de clase
class << self
def otro_metodo_clase
"Tambien llamado en clase"
end
end
end
Ejemplo.metodo_clase # "Llamado en clase"
Ejemplo.new.metodo_instancia # "Llamado en instancia"
```
## Busqueda de Metodos
```ruby
module A
def metodo
"A"
end
end
module B
def metodo
"B"
end
end
class C
include A
include B # B gana (ultimo incluido primero)
end
class D < C
end
puts D.new.metodo # "B" (cadena de busqueda: D -> C -> B -> A -> Object)
```
## Resumen
- `class` define una clase, `initialize` es el constructor
- `attr_accessor`, `attr_reader`, `attr_writer` crean getters/setters
- `@variable` es variable de instancia, `@@variable` es variable de clase
- `self.metodo` define metodo de clase
- `super` llama al metodo padre
- `include` agrega metodos de modulo como metodos de instancia
- `extend` agrega metodos de modulo como metodos de clase
- Control de acceso: `public`, `private`, `protected`
- Ruby usa duck typing (no se necesitan interfaces)
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →