Clases y Objetos
Introducción
En este capítulo se abordarán los conceptos básicos de la Programación Orientada a Objetos (POO) en Ruby. Se explicará cómo se definen las clases y cómo se crean objetos a partir de ellas. Se verán los conceptos de herencia y polimorfismo, y cómo se implementan en Ruby. También se explicará el uso de módulos y mixins para compartir comportamiento entre clases.
Conceptos básicos de la POO
La Programación Orientada a Objetos (POO) es un paradigma de programación que se basa en la definición de clases y objetos. Una clase es una plantilla que define la estructura y el comportamiento de un objeto, mientras que un objeto es una instancia de una clase.
En la POO, los objetos son entidades que tienen un estado (atributos) y un comportamiento (métodos). Los atributos representan las características de un objeto, mientras que los métodos representan las acciones que un objeto puede realizar.
En Ruby, todo es un objeto. Cada valor en Ruby es un objeto, incluso los números y las cadenas de texto. Por ejemplo, en Ruby podemos hacer operaciones con números como si fueran objetos:
puts 1 + 2
En este caso, 1 y 2 son objetos de la clase Fixnum que representan los números 1 y 2, respectivamente. El operador + es un método de la clase Fixnum que suma dos números.
Creación de Clases y Objetos
En Ruby, las clases se definen con la palabra clave class seguida del nombre de la clase y el cuerpo de la clase. Por ejemplo, la siguiente clase define un objeto de tipo Vehiculo con un atributo marca, modelo y un método mostrar:
class Vehiculo
def initialize(marca, modelo)
@marca = marca
@modelo = modelo
end
def mostrar
puts "Marca: #{@marca}"
puts "Modelo: #{@modelo}"
end
end
En este caso, la clase Vehiculo tiene un método initialize que inicializa los atributos marca y modelo y un método mostrar que imprime los atributos marca y modelo.
= Vehiculo.new("Toyota", "Corolla")
vehiculo .mostrar # Marca: Toyota, Modelo: Corolla vehiculo
En este caso, se crea un objeto de tipo Vehiculo con la marca “Toyota” y el modelo “Corolla” y se llama al método mostrar para imprimir los atributos marca y modelo.
Atributos y Métodos de Instancia
Los atributos de un objeto se definen con el prefijo * seguido del nombre del atributo. Los métodos de un objeto se definen con la palabra clave def** seguida del nombre del método y el cuerpo del método.
En el ejemplo anterior, el atributo nombre se define con el prefijo (nombre?) y el método saludar se define con la palabra clave def seguida del nombre del método y el cuerpo del método.
Ejemplos Prácticos
Ejemplo 1: Crear una clase y un objeto
En este ejemplo, se creará una clase Perro con un atributo nombre y un método ladrar. Se creará un objeto de tipo perro con el nombre “Firulais” y se llamará al método ladrar para imprimir el mensaje “Guau, guay, mi nombre es Firulais”.
class Perro
def initialize(nombre)
@nombre = nombre
end
def ladrar
puts "Guau, guau, mi nombre es #{@nombre}"
end
end
= Perro.new("Firulais")
perro .ladrar # Guau, guau, mi nombre es Firulais perro
En este caso, la clase Perro tiene un método initialize que inicializa el atributo nombre y un método ladrar que imprime un mensaje. Se crea un objeto de tipo Perro con el nombre “Firulais” y se llama al método ladrar para imprimir el mensaje “Guau, guau, mi nombre es Firulais”.
Ejemplo 2: Crear una clase con herencia
En este ejemplo, se creará una clase Deportes con un atributo nombre y un método practicar. Se creará una clase Futbol que hereda de la clase Deportes y tiene un atributo equipo y un método jugar. Se creará un objeto de tipo Futbol con el nombre “Lionel Messi” y el equipo “Barcelona” y se llamará al método practicar para imprimir el mensaje “Estoy practicando Lionel Messi”.
class Deportes
def initialize(nombre)
@nombre = nombre
end
def practicar
puts "Estoy practicando #{@nombre}"
end
end
class Futbol < Deportes
def initialize(nombre, equipo)
super(nombre)
@equipo = equipo
end
def jugar
puts "Estoy jugando al futbol en el equipo #{@equipo}"
end
end
= Futbol.new("Lionel Messi", "Barcelona")
futbolista .practicar # Estoy practicando Lionel Messi futbolista
En este caso, la clase Deportes tiene un método initialize que inicializa el atributo nombre y un método practicar que imprime un mensaje. La clase Futbol hereda de la clase Deportes y tiene un método initialize que inicializa el atributo equipo y un método jugar que imprime un mensaje.
Ejemplo 3: Crear un módulo y compartir comportamiento
En este ejemplo, se creará un módulo Saludar con un método saludar que imprime un mensaje. El módulo Saludar se incluirá en las clases Persona y Empleado para compartir el comportamiento. Se crearán objetos de tipo Persona y Empleado y se llamará al método saludar para imprimir el mensaje “Hola, soy una persona”.
class Persona
def saludar
puts "Hola, soy una persona"
end
end
class Empleado
def saludar
puts "Hola, soy un empleado"
end
end
module Saludar
def saludar
puts "Hola, soy una persona"
end
end
class Persona
include Saludar
end
class Empleado
include Saludar
end
= Persona.new
persona = Empleado.new
empleado
.saludar # Hola, soy una persona
persona.saludar # Hola, soy una persona empleado
En este caso, el módulo Saludar tiene un método saludar que imprime un mensaje. El módulo Saludar se incluye en las clases Persona y Empleado con la palabra clave include para compartir el comportamiento. Se crean objetos de tipo Persona y Empleado y se llama al método saludar para imprimir el mensaje “Hola, soy una persona”.
Ejercicios Prácticos
- Crear una clase Rectángulo con atributos base y altura y métodos para calcular el área y el perímetro del rectángulo.
- Crear una clase Cuadrado que hereda de la clase Rectángulo y tiene un método para calcular el área y el perímetro del cuadrado.
- Crear una clase Círculo con atributo radio y métodos para calcular el área y la circunferencia del círculo.
- Crear una clase Triángulo con atributos base y altura y métodos para calcular el área y el perímetro del triángulo.
- Crear una clase Figura con métodos para calcular el área y el perímetro de una figura geométrica genérica.
Herencia y Polimorfismo
En Ruby, la herencia y el polimorfismo son conceptos fundamentales de la Programación Orientada a Objetos (POO). La herencia permite que una clase herede los atributos y métodos de otra clase, mientras que el polimorfismo permite que un objeto se comporte de diferentes maneras según el contexto.
En Ruby, la herencia se define con la palabra clave < seguida del nombre de la clase de la que se hereda. Por ejemplo, la siguiente clase Empleado hereda de la clase Persona:
class Profesion
def initialize(profesion)
@profesion = profesion
end
def mostrar
puts "Profesión: #{@profesion}"
end
end
class Persona < Profesion
def initialize(nombre, profesion)
super(profesion)
@nombre = nombre
end
def saludar
puts "Hola, mi nombre es #{@nombre}"
end
end
= Persona.new("Juan", "Ingeniero")
persona .saludar # Hola, mi nombre es Juan
persona.mostrar # Profesión: Ingeniero persona
En este caso, la clase Persona hereda de la clase Profesion y tiene un método initialize que inicializa los atributos nombre y profesion y un método saludar que imprime un mensaje. Se crea un objeto de tipo Persona con el nombre “Juan” y la profesión “Ingeniero” y se llama a los métodos saludar y mostrar para imprimir los mensajes.
Polimorfismo
El polimorfismo es la capacidad de un objeto de comportarse de diferentes maneras según el contexto. En Ruby, el polimorfismo se logra mediante el uso de métodos polimórficos que se comportan de manera diferente según el tipo de objeto.
En el siguiente ejemplo, se define un método hablar en la clase Animal que lanza una excepción si se llama directamente. Las clases Perro y Gato heredan de la clase Animal y tienen un método hablar que imprime un mensaje. Se crean objetos de tipo Perro y Gato y se llama al método hablar para imprimir los mensajes “Guau, guau” y “Miau, miau”:
class Animal
def hablar
raise NotImplementedError, "Subclass must implement abstract method"
end
end
class Perro < Animal
def hablar
puts "Guau, guau"
end
end
class Gato < Animal
def hablar
puts "Miau, miau"
end
end
= Perro.new
perro = Gato.new
gato
.hablar # Guau, guau
perro.hablar # Miau, miau gato
En este caso, la clase Animal tiene un método hablar que lanza una excepción si se llama directamente. Las clases Perro y Gato heredan de la clase Animal y tienen un método hablar que imprime un mensaje. Se crean objetos de tipo Perro y Gato y se llama al método hablar para imprimir los mensajes “Guau, guau” y “Miau, miau”.
Módulos y Mixins
En Ruby, los módulos son una forma de compartir comportamiento entre clases. Un módulo es un contenedor de métodos y constantes que se pueden incluir en una clase para agregar funcionalidad. Los módulos se incluyen en una clase con la palabra clave include.
En el siguiente ejemplo, se define un módulo Saludar con un método saludar que imprime un mensaje. El módulo Saludar se incluye en las clases Persona y Empleado para compartir el comportamiento:
module Saludar
def saludar
puts "Hola, soy una persona"
end
end
class Persona
include Saludar
end
class Empleado
include Saludar
end
= Persona.new
persona = Empleado.new
empleado
.saludar # Hola, soy una persona
persona.saludar # Hola, soy una persona empleado
En este caso, el módulo Saludar tiene un método saludar que imprime un mensaje. El módulo Saludar se incluye en las clases Persona y Empleado con la palabra clave include para compartir el comportamiento. Se crean objetos de tipo Persona y Empleado y se llama al método saludar para imprimir el mensaje “Hola, soy una persona”.
Ejercicios Prácticos
Crear una clase Vehículo con atributos marca y modelo y métodos para mostrar la marca y el modelo del vehículo.
Crear una clase Automóvil que hereda de la clase Vehículo y tiene un atributo color y un método para mostrar el color del automóvil.
Crear una clase Motocicleta que hereda de la clase Vehículo y tiene un atributo cilindrada y un método para mostrar la cilindrada de la motocicleta.
Crear una clase Camión que hereda de la clase Vehículo y tiene un atributo carga y un método para mostrar la carga del camión.
Crear una clase Transporte con métodos para mostrar la marca y el modelo de un vehículo genérico.
Conclusiones
En este capítulo se han abordado los conceptos básicos de la Programación Orientada a Objetos (POO) en Ruby. Se ha explicado cómo se definen las clases y cómo se crean objetos a partir de ellas. Se han visto los conceptos de herencia y polimorfismo, y cómo se implementan en Ruby. También se ha explicado el uso de módulos y mixins para compartir comportamiento entre clases.
En resumen, la POO es un paradigma de programación que se basa en la definición de clases y objetos. En Ruby, las clases se definen con la palabra clave class seguida del nombre de la clase y el cuerpo de la clase. Los objetos se crean a partir de una clase con el método new y se pueden llamar a los métodos de la clase con el operador .. La herencia permite que una clase herede los atributos y métodos de otra clase, mientras que el polimorfismo permite que un objeto se comporte de diferentes maneras según el contexto. Los módulos y mixins permiten compartir comportamiento entre clases.
En los ejemplos prácticos se han creado clases y objetos para representar diferentes entidades y se ha mostrado cómo se pueden compartir comportamientos entre clases. Se han creado clases con herencia y polimorfismo para mostrar cómo se pueden reutilizar y extender funcionalidades. Se han creado módulos y mixins para compartir comportamientos entre clases y se ha mostrado cómo se pueden incluir en las clases para agregar funcionalidades.