CLASES en PYTHON, TODOS los pilares de POO aplicados a un EJEMPLO COMPLETO desde CERO
Clases en Python para Principiantes
¿Qué es una clase?
Imagina que una clase es como un molde o plantilla para crear objetos. Por ejemplo, si quieres hacer galletas, usas un molde. La clase sería el molde, y cada galleta sería un objeto.
Conceptos básicos
Clase: Molde o plantilla
Objeto: Instancia creada a partir de la clase
Atributos: Características del objeto (como variables)
Métodos: Acciones que puede realizar el objeto (como funciones)
Sintaxis básica
class NombreClase:
# Atributos y métodos van aquí
passEjemplo práctico: Crear una clase "Perro"
class Perro:
# Método especial: se ejecuta al crear un objeto
def __init__(self, nombre, raza, edad):
# Atributos de instancia
self.nombre = nombre
self.raza = raza
self.edad = edad
# Método (función dentro de la clase)
def ladrar(self):
return f"{self.nombre} dice: ¡Guau!"
def describir(self):
return f"{self.nombre} es un {self.raza} de {self.edad} años"Crear objetos (instancias)
# Crear objetos a partir de la clase Perro
perro1 = Perro("Max", "Labrador", 3)
perro2 = Perro("Luna", "Pastor Alemán", 2)
# Usar los métodos
print(perro1.ladrar()) # Max dice: ¡Guau!
print(perro2.describir()) # Luna es un Pastor Alemán de 2 años
# Acceder a los atributos
print(perro1.nombre) # Max
print(perro2.edad) # 2¿Qué es self?
selfse refiere a la instancia actual del objetoEs como decir "yo mismo" o "este objeto"
Siempre es el primer parámetro de los métodos
Método __init__
Es el constructor de la clase
Se ejecuta automáticamente cuando creas un nuevo objeto
Se usa para inicializar los atributos
Ejemplo más completo: Cuenta Bancaria
class CuentaBancaria:
def __init__(self, titular, saldo_inicial=0):
self.titular = titular
self.saldo = saldo_inicial
def depositar(self, cantidad):
self.saldo += cantidad
return f"Depósito exitoso. Saldo actual: ${self.saldo}"
def retirar(self, cantidad):
if cantidad <= self.saldo:
self.saldo -= cantidad
return f"Retiro exitoso. Saldo actual: ${self.saldo}"
else:
return "Fondos insuficientes"
def consultar_saldo(self):
return f"Saldo de {self.titular}: ${self.saldo}"
# Usar la clase
cuenta1 = CuentaBancaria("Ana", 1000)
cuenta2 = CuentaBancaria("Carlos", 500)
print(cuenta1.consultar_saldo()) # Saldo de Ana: $1000
print(cuenta1.depositar(200)) # Depósito exitoso. Saldo actual: $1200
print(cuenta1.retirar(300)) # Retiro exitoso. Saldo actual: $900Ventajas de usar clases
Organización: Código más ordenado y fácil de entender
Reutilización: Puedes crear muchos objetos de la misma clase
Modularidad: Fácil de modificar y mantener
Abstracción: Ocultas la complejidad interna
Resumen visual
CLASE Perro (molde)
│
├── Atributos: nombre, raza, edad
│
└── Métodos: ladrar(), describir()
│
↓
OBJETOS (galletas del molde)
│
├── perro1: nombre="Max", raza="Labrador", edad=3
│
└── perro2: nombre="Luna", raza="Pastor Alemán", edad=2Consejos para principiantes
Empieza simple: Crea clases básicas primero
Nombres descriptivos: Usa nombres que expliquen qué hace la clase
Practica: Crea clases para cosas de la vida real (coche, libro, persona)
No te rindas: Al principio puede ser confuso, pero con práctica se entiende
Tutorial de Clases en Python: Ejemplo Original de Personajes RPG
Voy a crear un tutorial completo basado en ese contenido, con un ejemplo práctico de un sistema de personajes RPG.
1. Abstracción - Creando nuestra Clase Base
# Clase Personaje (nuestra plantilla/matriz)
class Personaje:
def __init__(self, nombre, fuerza, inteligencia, defensa, vida):
# Atributos de instancia
self.nombre = nombre
self.fuerza = fuerza
self.inteligencia = inteligencia
self.defensa = defensa
self.vida = vida
self.vida_maxima = vida # Para poder curarse luego
self.aguante = fuerza * vida # Atributo derivado
self.turno = False # Atributo independiente
def atributos(self):
"""Muestra los atributos del personaje"""
print(f"{self.nombre}:")
print(f"• Fuerza: {self.fuerza}")
print(f"• Inteligencia: {self.inteligencia}")
print(f"• Defensa: {self.defensa}")
print(f"• Vida: {self.vida}")
print(f"• Aguante: {self.aguante}")
def subir_nivel(self, fuerza=0, inteligencia=0, defensa=0):
"""Mejora las estadísticas del personaje"""
self.fuerza += fuerza
self.inteligencia += inteligencia
self.defensa += defensa
self.aguante = self.fuerza * self.vida # Recalculamos aguante
def esta_vivo(self):
"""Verifica si el personaje está vivo"""
return self.vida > 0
def morir(self):
"""Marca al personaje como muerto"""
self.vida = 0
print(f"💀 {self.nombre} ha muerto")
def daño(self, enemigo):
"""Calcula el daño que haría a un enemigo"""
return self.fuerza - enemigo.defensa
def atacar(self, enemigo):
"""Realiza un ataque a otro personaje"""
daño = self.daño(enemigo)
enemigo.vida -= daño
print(f"⚔️ {self.nombre} ataca a {enemigo.nombre}")
print(f"💥 Causa {daño} puntos de daño")
if enemigo.esta_vivo():
print(f"❤️ {enemigo.nombre} tiene {enemigo.vida} puntos de vida")
else:
enemigo.morir()
def curar(self, puntos_curacion=10):
"""Cura al personaje"""
if self.esta_vivo():
self.vida = min(self.vida + puntos_curacion, self.vida_maxima)
print(f"✨ {self.nombre} se cura {puntos_curacion} puntos")
print(f"❤️ Vida actual: {self.vida}/{self.vida_maxima}")
else:
print(f"❌ {self.nombre} está muerto, no se puede curar")2. Probando nuestra Clase Base
# Creando personajes
heroe = Personaje("Aragorn", fuerza=15, inteligencia=10, defensa=8, vida=100)
villano = Personaje("Sauron", fuerza=18, inteligencia=12, defensa=6, vida=80)
# Mostrando atributos
print("=== ATRIBUTOS INICIALES ===")
heroe.atributos()
print()
villano.atributos()
# Probando métodos
print("\n=== SUBIENDO DE NIVEL ===")
heroe.subir_nivel(fuerza=2, inteligencia=1, defensa=1)
heroe.atributos()
print("\n=== COMBATE ===")
heroe.atacar(villano)
villano.atacar(heroe)
print("\n=== CURACIÓN ===")
heroe.curar(15)3. Herencia - Creando Clases Especializadas
class Guerrero(Personaje):
def __init__(self, nombre, fuerza, inteligencia, defensa, vida, espada):
# Llamamos al constructor de la clase padre
super().__init__(nombre, fuerza, inteligencia, defensa, vida)
self.espada = espada # Daño adicional de la espada
def cambiar_arma(self):
"""Permite cambiar el arma del guerrero"""
print("\n🗡️ Selecciona un arma:")
print("1. Espada de acero - Daño: 8")
print("2. Hacha de guerra - Daño: 12")
print("3. Martillo de thor - Daño: 15")
try:
opcion = int(input("Elige (1-3): "))
if opcion == 1:
self.espada = 8
elif opcion == 2:
self.espada = 12
elif opcion == 3:
self.espada = 15
else:
print("❌ Opción inválida, manteniendo arma actual")
except:
print("❌ Error al seleccionar arma")
def atributos(self):
"""Sobreescribe el método para mostrar también el arma"""
super().atributos()
print(f"• Daño de espada: {self.espada}")
def daño(self, enemigo):
"""Sobreescribe el cálculo de daño"""
return (self.fuerza * self.espada) - enemigo.defensa
class Mago(Personaje):
def __init__(self, nombre, fuerza, inteligencia, defensa, vida, libro):
super().__init__(nombre, fuerza, inteligencia, defensa, vida)
self.libro = libro # Multiplicador de hechizos
def atributos(self):
"""Sobreescribe el método para mostrar también el libro"""
super().atributos()
print(f"• Poder del libro: {self.libro}")
def daño(self, enemigo):
"""Sobreescribe el cálculo de daño usando inteligencia"""
return (self.inteligencia * self.libro) - enemigo.defensa
def lanzar_hechizo(self, enemigo):
"""Método exclusivo del mago"""
if self.inteligencia > 10:
daño_extra = self.inteligencia * 2
enemigo.vida -= daño_extra
print(f"🔮 {self.nombre} lanza un hechizo poderoso!")
print(f"✨ Causa {daño_extra} puntos de daño mágico")
else:
print(f"❌ {self.nombre} no tiene suficiente inteligencia para lanzar hechizos")4. Probando la Herencia
# Creando personajes especializados
guerrero = Guerrero("Guts", fuerza=20, inteligencia=5, defensa=10, vida=120, espada=8)
mago = Mago("Gandalf", fuerza=8, inteligencia=18, defensa=6, vida=90, libro=3)
print("=== GUERRERO ===")
guerrero.atributos()
print("\n=== MAGO ===")
mago.atributos()
print("\n=== COMBATE ESPECIALIZADO ===")
guerrero.atacar(mago)
mago.atacar(guerrero)
# Probando métodos exclusivos
print("\n=== HECHIZO MAGICO ===")
mago.lanzar_hechizo(guerrero)
print("\n=== CAMBIANDO ARMA ===")
guerrero.cambiar_arma()
guerrero.atributos()5. Polimorfismo - Sistema de Combate
def combate(jugador1, jugador2):
"""Función que puede recibir cualquier tipo de personaje"""
print(f"🎯 COMIENZA EL COMBATE: {jugador1.nombre} vs {jugador2.nombre}")
print("=" * 50)
turno = 0
while jugador1.esta_vivo() and jugador2.esta_vivo():
turno += 1
print(f"\n--- TURNO {turno} ---")
# Jugador 1 ataca a Jugador 2
if jugador1.esta_vivo():
jugador1.atacar(jugador2)
# Jugador 2 ataca a Jugador 1
if jugador2.esta_vivo():
jugador2.atacar(jugador1)
# Determinar ganador
print("\n" + "=" * 50)
if jugador1.esta_vivo():
print(f"🏆 {jugador1.nombre} GANA EL COMBATE!")
elif jugador2.esta_vivo():
print(f"🏆 {jugador2.nombre} GANA EL COMBATE!")
else:
print("💀 EMPATE - Ambos combatientes han muerto")
def que_soy(personaje):
"""Ejemplo de polimorfismo"""
print(f"Soy un {type(personaje).__name__} llamado {personaje.nombre}")
# Probando el sistema de combate
print("=== SISTEMA DE COMBATE ===")
arquero = Personaje("Legolas", fuerza=12, inteligencia=14, defensa=7, vida=95)
paladin = Guerrero("Uther", fuerza=16, inteligencia=12, defensa=12, vida=110, espada=10)
combate(arquero, paladin)
print("\n=== POLIMORFISMO ===")
personajes = [heroe, guerrero, mago, arquero, paladin]
for p in personajes:
que_soy(p)6. Encapsulación (Opcional - Para Entender el Concepto)
class PersonajeProtegido:
def __init__(self, nombre, fuerza):
self.__nombre = nombre # Atributo "privado"
self.__fuerza = fuerza
# Getters
def get_nombre(self):
return self.__nombre
def get_fuerza(self):
return self.__fuerza
# Setters con validación
def set_fuerza(self, nueva_fuerza):
if nueva_fuerza < 0:
print("❌ La fuerza no puede ser negativa")
else:
self.__fuerza = nueva_fuerza
print(f"✅ Fuerza cambiada a: {nueva_fuerza}")
# Probando encapsulación
pj_protegido = PersonajeProtegido("Protector", 10)
print(f"Nombre: {pj_protegido.get_nombre()}")
pj_protegido.set_fuerza(-5) # Esto mostrará error
pj_protegido.set_fuerza(15) # Esto funcionará7. Ejemplo Completo: Arena de Combate
class Arena:
def __init__(self, nombre):
self.nombre = nombre
self.combatientes = []
def agregar_combatiente(self, personaje):
self.combatientes.append(personaje)
print(f"✅ {personaje.nombre} se une a la arena {self.nombre}")
def torneo(self):
print(f"\n🏟️ COMIENZA EL TORNEO EN {self.nombre}")
print("=" * 60)
for i in range(len(self.combatientes)):
for j in range(i + 1, len(self.combatientes)):
# Restauramos la vida para el torneo
self.combatientes[i].vida = self.combatientes[i].vida_maxima
self.combatientes[j].vida = self.combatientes[j].vida_maxima
print(f"\n🎯 ENFRENTAMIENTO: {self.combatientes[i].nombre} vs {self.combatientes[j].nombre}")
combate(self.combatientes[i], self.combatientes[j])
# Creando una arena y organizando un torneo
arena_epica = Arena("Coliseo del Dragón")
# Agregando combatientes
arena_epica.agregar_combatiente(guerrero)
arena_epica.agregar_combatiente(mago)
arena_epica.agregar_combatiente(arquero)
arena_epica.agregar_combatiente(paladin)
# Iniciando torneo
arena_epica.torneo()Resumen de Conceptos Aprendidos:
Abstracción: Creamos la clase
Personajecomo moldeEncapsulación: Protegemos atributos con getters/setters
Herencia:
GuerreroyMagoheredan dePersonajePolimorfismo: Mismo método
atacar()se comporta diferente según la clase
Ejercicios para Practicar:
Crea una clase
Arqueroque herede dePersonajeImplementa un sistema de experiencia y niveles
Crea un método
usar_pocion()que cure al personajeImplementa ataques especiales para cada clase
Comentarios
Publicar un comentario