La Programación Orientada a Objetos (POO) en Python es uno de los paradigmas más importantes del desarrollo de software. Dominar clases, herencia, polimorfismo y encapsulamiento es imprescindible para trabajar con frameworks como Django, FastAPI o Scrapy, y para superar entrevistas técnicas en empresas de tecnología. En este artículo encontrarás ejercicios de POO en Python resueltos con código completo y explicación paso a paso.
¿Qué es la POO en Python?
La POO organiza el código en clases (plantillas) y objetos (instancias concretas). Los cuatro pilares son:
- Encapsulamiento: ocultar el estado interno y exponer solo lo necesario
- Herencia: reutilizar código de una clase padre en clases hijas
- Polimorfismo: distintos objetos responden al mismo método de formas diferentes
- Abstracción: definir interfaces sin exponer la implementación
Ejercicio 1 — Primera clase: Persona
class Persona:
def __init__(self, nombre, edad):
self.nombre = nombre
self.edad = edad
def presentarse(self):
return f"Hola, soy {self.nombre} y tengo {self.edad} anos."
def __repr__(self):
return f"Persona({self.nombre!r}, {self.edad})"
p = Persona("Ana", 30)
print(p.presentarse())
# Hola, soy Ana y tengo 30 anos.
Ejercicio 2 — Encapsulamiento con propiedades
class CuentaBancaria:
def __init__(self, titular, saldo_inicial=0):
self._titular = titular
self.__saldo = saldo_inicial # atributo privado
@property
def saldo(self):
return self.__saldo
def depositar(self, cantidad):
if cantidad > 0:
self.__saldo += cantidad
return True
return False
def retirar(self, cantidad):
if 0 < cantidad <= self.__saldo:
self.__saldo -= cantidad
return True
return False
cuenta = CuentaBancaria("Luis", 1000)
cuenta.depositar(500)
cuenta.retirar(200)
print(cuenta.saldo) # 1300
Ejercicio 3 — Herencia
class Animal:
def __init__(self, nombre, sonido):
self.nombre = nombre
self.sonido = sonido
def hablar(self):
return f"{self.nombre} dice: {self.sonido}"
class Perro(Animal):
def __init__(self, nombre):
super().__init__(nombre, "Guau!")
def buscar(self, objeto):
return f"{self.nombre} va a buscar {objeto}"
class Gato(Animal):
def __init__(self, nombre):
super().__init__(nombre, "Miau!")
perro = Perro("Rex")
gato = Gato("Mimi")
print(perro.hablar()) # Rex dice: Guau!
print(gato.hablar()) # Mimi dice: Miau!
print(perro.buscar("pelota"))# Rex va a buscar pelota
Ejercicio 4 — Polimorfismo
class Forma:
def area(self):
raise NotImplementedError
def __str__(self):
return f"{self.__class__.__name__}: area = {self.area():.2f}"
class Circulo(Forma):
def __init__(self, radio):
self.radio = radio
def area(self):
return 3.14159 * self.radio ** 2
class Rectangulo(Forma):
def __init__(self, ancho, alto):
self.ancho = ancho
self.alto = alto
def area(self):
return self.ancho * self.alto
formas = [Circulo(5), Rectangulo(4, 6), Circulo(3)]
for forma in formas:
print(forma)
# Circulo: area = 78.54
# Rectangulo: area = 24.00
# Circulo: area = 28.27
Ejercicio 5 — Herencia múltiple y MRO
class Volador:
def mover(self):
return "Volando"
class Nadador:
def mover(self):
return "Nadando"
class Pato(Volador, Nadador):
def quack(self):
return "Cuac!"
pato = Pato()
print(pato.mover()) # Volando (MRO: Pato -> Volador -> Nadador)
print(pato.quack()) # Cuac!
print(Pato.__mro__) # muestra la cadena de resolución
Ejercicio 6 — Métodos de clase y estáticos
class Temperatura:
_conversiones = 0
def __init__(self, celsius):
self.celsius = celsius
@classmethod
def desde_fahrenheit(cls, fahrenheit):
cls._conversiones += 1
return cls((fahrenheit - 32) * 5 / 9)
@staticmethod
def punto_congelacion():
return "El agua congela a 0 C / 32 F"
@property
def fahrenheit(self):
return self.celsius * 9 / 5 + 32
t = Temperatura.desde_fahrenheit(100)
print(f"{t.celsius:.1f} C") # 37.8 C
print(Temperatura.punto_congelacion())
Ejercicio 7 — Clase abstracta con ABC
from abc import ABC, abstractmethod
class Vehiculo(ABC):
def __init__(self, marca, modelo):
self.marca = marca
self.modelo = modelo
@abstractmethod
def combustible(self):
pass
def info(self):
return f"{self.marca} {self.modelo} ({self.combustible()})"
class Coche(Vehiculo):
def combustible(self):
return "Gasolina"
class CocheElectrico(Vehiculo):
def combustible(self):
return "Electrico"
coches = [Coche("Toyota", "Corolla"), CocheElectrico("Tesla", "Model 3")]
for c in coches:
print(c.info())
Preguntas frecuentes sobre POO en Python
¿Qué es una clase en Python y para qué sirve?
Una clase es una plantilla que define los atributos (datos) y métodos (comportamientos) que tendrán los objetos creados a partir de ella. Se define con la palabra clave class y se instancia llamándola como función: mi_objeto = MiClase(). Sirve para organizar el código en unidades lógicas reutilizables y modelar entidades del mundo real en el programa.
¿Qué es la herencia en Python?
La herencia permite crear una clase nueva (hija) que reutiliza el código de otra clase existente (padre). La clase hija hereda todos los atributos y métodos del padre, puede sobrescribirlos y añadir los suyos propios. Se define con class Hija(Padre):. Python admite herencia múltiple: class C(A, B):, resolviendo conflictos mediante el MRO (Method Resolution Order).
¿Cuál es la diferencia entre @classmethod y @staticmethod?
Un @classmethod recibe la clase como primer argumento (cls) y puede acceder al estado de la clase o crear instancias alternativas. Un @staticmethod no recibe ni instancia ni clase, actúa como una función normal dentro del espacio de nombres de la clase. Usa @classmethod para métodos de fábrica y @staticmethod para utilidades relacionadas con la clase pero sin acceso a su estado.
¿Qué es el polimorfismo en Python?
El polimorfismo permite que objetos de diferentes clases respondan al mismo método de formas distintas. En Python es especialmente natural gracias al duck typing: si un objeto tiene el método area(), puede usarse en cualquier lugar que espere ese método, sin importar su clase. Esto hace el código flexible y extensible sin necesidad de comprobaciones de tipo.
Conclusión
La POO en Python es un pilar del desarrollo profesional. Practica estos ejercicios y continúa con los ejercicios de funciones en Python, los ejercicios generales de Python y los patrones de diseño en Python para consolidar tus conocimientos.