Programación Orientada a Objetos en Python: Clases y Objetos
Programación Orientada a Objetos en Python: Clases, Objetos y Herencia
Aprende Programación Orientada a Objetos (POO) en Python desde cero. Clases, objetos, atributos, métodos, herencia y polimorfismo con ejercicios resueltos paso a paso.
1¿Qué es la Programación Orientada a Objetos?
La Programación Orientada a Objetos (POO) es un paradigma que organiza el código en torno a objetos: entidades que combinan datos (atributos) y comportamientos (métodos). Es la base de frameworks como Django y librerías como Pandas.
| Concepto | Analogía | En Python |
|---|---|---|
| Clase | Plano arquitectónico | class Persona: |
| Objeto | Casa construida con ese plano | p = Persona("Ana") |
| Atributo | Características (color, tamaño) | p.nombre = "Ana" |
| Método | Acciones (abrir puerta, encender luz) | p.saludar() |
2Crear una clase: class e __init__
Una clase se define con la palabra clave class. El método especial __init__ es el constructor: se ejecuta automáticamente cuando se crea un objeto.
class Persona: """Clase que representa a una persona""" def __init__(self, nombre, edad): # Atributos de instancia self.nombre = nombre self.edad = edad def saludar(self): print(f"Hola, me llamo {self.nombre} y tengo {self.edad} años") def cumpleanos(self): self.edad += 1 print(f"🎂 ¡Feliz cumpleaños {self.nombre}! Ahora tienes {self.edad} años") # Crear objetos (instancias) de la clase persona1 = Persona("Ana", 25) persona2 = Persona("Luis", 30) # Llamar métodos persona1.saludar() persona2.saludar() persona1.cumpleanos() # Acceder a atributos directamente print(f"Nombre: {persona1.nombre}, Edad: {persona1.edad}")
Hola, me llamo Ana y tengo 25 años Hola, me llamo Luis y tengo 30 años 🎂 ¡Feliz cumpleaños Ana! Ahora tienes 26 años Nombre: Ana, Edad: 26
3Atributos y métodos
Existen dos tipos de atributos: los de instancia (únicos para cada objeto) y los de clase (compartidos por todos los objetos).
class CuentaBancaria: banco = "Banco Python" # Atributo de clase (compartido) tasa_interes = 0.05 # Atributo de clase def __init__(self, titular, saldo_inicial=0): self.titular = titular # Atributo de instancia self.saldo = saldo_inicial # Atributo de instancia self.movimientos = [] def depositar(self, monto): self.saldo += monto self.movimientos.append(f"+{monto}") print(f"✅ Depósito: ${monto:,.0f} | Saldo: ${self.saldo:,.0f}") def retirar(self, monto): if monto > self.saldo: print("❌ Saldo insuficiente") else: self.saldo -= monto self.movimientos.append(f"-{monto}") print(f"💸 Retiro: ${monto:,.0f} | Saldo: ${self.saldo:,.0f}") def ver_estado(self): print(f"\n=== Cuenta de {self.titular} ({self.banco}) ===") print(f"Saldo actual: ${self.saldo:,.0f}") print(f"Movimientos: {self.movimientos}") # Crear y usar la cuenta cuenta = CuentaBancaria("Ana García", 500000) cuenta.depositar(200000) cuenta.retirar(100000) cuenta.retirar(900000) cuenta.ver_estado()
✅ Depósito: $200,000 | Saldo: $700,000 💸 Retiro: $100,000 | Saldo: $600,000 ❌ Saldo insuficiente === Cuenta de Ana García (Banco Python) === Saldo actual: $600,000 Movimientos: ['+200000', '-100000']
4¿Qué es self?
self es una referencia al propio objeto. Cuando llamas cuenta.depositar(200), Python traduce eso internamente a CuentaBancaria.depositar(cuenta, 200). self siempre debe ser el primer parámetro de cada método.
self.nombre_atributo. Sin self, Python crearía una variable local que desaparece al terminar el método.5Herencia
La herencia permite crear una clase nueva basada en una existente, reutilizando y extendiendo su funcionalidad. La clase original se llama clase padre y la nueva es la clase hija.
# Clase padre (base) class Animal: def __init__(self, nombre, edad): self.nombre = nombre self.edad = edad def info(self): print(f"{self.nombre} ({self.edad} años)") def sonido(self): print("... (sonido genérico)") # Clases hijas (heredan de Animal) class Perro(Animal): def __init__(self, nombre, edad, raza): super().__init__(nombre, edad) # llama al __init__ del padre self.raza = raza def sonido(self): # Sobreescribe el método del padre print(f"{self.nombre} dice: ¡Guau guau! 🐕") def info(self): super().info() # llama al método del padre print(f" Raza: {self.raza}") class Gato(Animal): def __init__(self, nombre, edad, indoor): super().__init__(nombre, edad) self.indoor = indoor def sonido(self): print(f"{self.nombre} dice: ¡Miau! 🐈") # Crear objetos perro = Perro("Rex", 3, "Labrador") gato = Gato("Luna", 2, True) perro.info() perro.sonido() gato.info() gato.sonido()
Rex (3 años) Raza: Labrador Rex dice: ¡Guau guau! 🐕 Luna (2 años) Luna dice: ¡Miau! 🐈
6Polimorfismo
El polimorfismo permite tratar objetos de distintas clases de forma uniforme. Si todas tienen el mismo método, puedes llamarlo sin importar qué tipo de objeto sea.
# Polimorfismo: mismo método, distintos comportamientos animales = [ Perro("Rex", 3, "Labrador"), Gato("Luna", 2, True), Perro("Max", 5, "Poodle"), Gato("Misi", 1, False), ] print("=== TODOS LOS ANIMALES HACEN RUIDO ===") for animal in animales: animal.sonido() # cada uno responde diferente
=== TODOS LOS ANIMALES HACEN RUIDO === Rex dice: ¡Guau guau! 🐕 Luna dice: ¡Miau! 🐈 Max dice: ¡Guau guau! 🐕 Misi dice: ¡Miau! 🐈
7🏋️ Ejercicio: Sistema de Biblioteca
Implementa un sistema básico de biblioteca con clases Libro y Biblioteca. Debe permitir agregar libros, buscar por título o autor, y mostrar el catálogo.
class Libro: def __init__(self, titulo, autor, anio, disponible=True): self.titulo = titulo self.autor = autor self.anio = anio self.disponible = disponible def __str__(self): estado = "✅ Disponible" if self.disponible else "❌ Prestado" return f'"{self.titulo}" — {self.autor} ({self.anio}) [{estado}]' class Biblioteca: def __init__(self, nombre): self.nombre = nombre self.libros = [] def agregar_libro(self, libro): self.libros.append(libro) print(f"📚 Libro agregado: {libro.titulo}") def buscar_titulo(self, texto): encontrados = [l for l in self.libros if texto.lower() in l.titulo.lower()] print(f"\n🔍 Resultados para '{texto}':") for l in encontrados: print(f" {l}") return encontrados def prestar(self, titulo): for libro in self.libros: if libro.titulo == titulo: if libro.disponible: libro.disponible = False print(f"📖 Prestado: {titulo}") else: print(f"❌ No disponible: {titulo}") return print("Libro no encontrado") def catalogo(self): print(f"\n=== {self.nombre} — Catálogo ({len(self.libros)} libros) ===") for libro in self.libros: print(f" {libro}") # Prueba del sistema bib = Biblioteca("Biblioteca Central") bib.agregar_libro(Libro("Python Crash Course", "Eric Matthes", 2019)) bib.agregar_libro(Libro("Automate with Python", "Al Sweigart", 2020)) bib.agregar_libro(Libro("Fluent Python", "Luciano Ramalho", 2022)) bib.catalogo() bib.prestar("Fluent Python") bib.prestar("Fluent Python") # Intento de nuevo préstamo bib.catalogo()
📚 Libro agregado: Python Crash Course 📚 Libro agregado: Automate with Python 📚 Libro agregado: Fluent Python === Biblioteca Central — Catálogo (3 libros) === "Python Crash Course" — Eric Matthes (2019) [✅ Disponible] "Automate with Python" — Al Sweigart (2020) [✅ Disponible] "Fluent Python" — Luciano Ramalho (2022) [✅ Disponible] 📖 Prestado: Fluent Python ❌ No disponible: Fluent Python === Biblioteca Central — Catálogo (3 libros) === "Python Crash Course" — Eric Matthes (2019) [✅ Disponible] "Automate with Python" — Al Sweigart (2020) [✅ Disponible] "Fluent Python" — Luciano Ramalho (2022) [❌ Prestado]
¿Aprendiste POO en Python? 🏆
¡Déjanos tus preguntas en los comentarios! Comparte con tus compañeros y suscríbete para más ejercicios resueltos cada semana.
- Manejo de archivos en Python: leer y escribir ficheros
- Excepciones en Python: try, except, finally
- Módulos y paquetes en Python
Comentarios
Publicar un comentario