Programación Orientada a Objetos en Python: Herencia, Polimorfismo y Referencias con Ejemplos Prácticos
Programación orientada a objetos en Python: herencia y polimorfismo
A continuación se presenta un ejemplo completo de programación orientada a objetos en Python, en el que se modelan personas, empleados, directivos y clientes de una empresa.
1. Clase base: Persona
La clase Persona es la clase base del ejemplo. Define los atributos nombre y edad, así como el método mostrar_datos(), que devuelve una cadena con los datos básicos.
class Persona:
def __init__(self, nombre, edad):
self.nombre = nombre
self.edad = edad
def mostrar_datos(self):
"""Devuelve una cadena con los datos básicos de la persona."""
return f"Nombre: {self.nombre}, Edad: {self.edad}"2. Herencia: clase Empleado
La clase Empleado hereda de Persona mediante herencia y utiliza super() para reutilizar el constructor de la clase padre. Además, sobrescribe el método mostrar_datos() para añadir el sueldo bruto y la categoría.
class Empleado(Persona):
def __init__(self, nombre, edad, sueldo_bruto, categoria):
super().__init__(nombre, edad)
self.categoria = categoria
self.sueldo_bruto = sueldo_bruto
def mostrar_datos_cliente(self, cliente):
print(f"Datos del cliente vistos por {self.nombre}:")
print(cliente.mostrar_datos())
def mostrar_datos(self):
return (
f"{super().mostrar_datos()}, Sueldo bruto: {self.sueldo_bruto:.2f} €, "
f"Categoria: {self.categoria}"
)3. Herencia multinivel: clase Directivo
La clase Directivo hereda de Empleado, creando una herencia multinivel (Persona → Empleado → Directivo). Incorpora una lista de subordinados y sobrescribe nuevamente mostrar_datos().
class Directivo(Empleado):
def __init__(self, nombre, edad, sueldo_bruto, categoria):
super().__init__(nombre, edad, sueldo_bruto, categoria)
self.subordinados = []
def agregar_subordinado(self, empleado):
self.subordinados.append(empleado)
def mostrar_datos(self):
sub_nombres = ", ".join([s.nombre for s in self.subordinados]) or "Ninguno"
return (
f"{super().mostrar_datos()}, Categoría: {self.categoria}, "
f"Subordinados: {sub_nombres}"
)4. Clase Cliente
La clase Cliente también hereda de Persona y añade el atributo teléfono.
class Cliente(Persona):
def __init__(self, nombre, edad, telefono):
super().__init__(nombre, edad)
self.telefono = telefono
def mostrar_datos(self):
return f"{super().mostrar_datos()}, Teléfono: {self.telefono}"5. Programa principal
El bloque if __name__ == "__main__": solo se ejecuta cuando el archivo se ejecuta directamente, y no cuando se importa como módulo. En él se crean los objetos, se establecen las relaciones entre ellos y se muestran sus datos.
if __name__ == "__main__":
emp1 = Empleado("Ana López", 30, 25000, 'Empleado')
emp2 = Empleado("Luis Pérez", 28, 23000, 'Empleado')
jefe = Directivo("Marta Gómez", 45, 50000, "Gerente")
jefe.agregar_subordinado(emp1)
jefe.agregar_subordinado(emp2)
cliente1 = Cliente("Carlos Ruiz", 40, "600123456")
cliente2 = Cliente("Juana Soler", 40, "658258742")
cliente3 = cliente2
personas = [emp1, emp2, jefe, cliente1, cliente2]
print("=== Datos de personas en la empresa ===")
for p in personas:
print(p.mostrar_datos())
if cliente2 == cliente3:
print('cliente 2 y cliente 3 apuntan a la misma dirección de memoria')
else:
print('cliente 2 y cliente 3 no apuntan a la misma dirección de memoria')
print(cliente2.mostrar_datos())
emp2.mostrar_datos_cliente(cliente3)6. Conceptos clave demostrados
- Herencia: Empleado, Directivo y Cliente heredan de Persona.
- Polimorfismo: el bucle for llama a mostrar_datos() sobre objetos de distintas clases y cada uno responde según su propia implementación.
- super(): permite invocar el constructor y los métodos de la clase padre.
- Composición de objetos: un Directivo contiene una lista de Empleados subordinados.
- Referencias en memoria: cliente3 es una referencia al mismo objeto que cliente2, por lo que la comparación con == confirma que ambas apuntan al mismo objeto.