La herencia en Python es clave para escribir código limpio y evitar duplicación en proyectos reales como un sistema de biblioteca. Con una estructura similar a un árbol genealógico, permite que clases hijas reutilicen atributos y métodos de una clase padre, manteniendo la lógica central en un solo lugar y habilitando comportamientos específicos donde haga falta.
¿Qué es la herencia en Python y por qué evita duplicación?
La herencia establece relaciones de “es un tipo de”: un Estudiante es un tipo de Usuario, igual que un Profesor. Así, las clases hijas heredan atributos y métodos del padre, y los cambios en la clase base se propagan automáticamente. Además, el override permite redefinir métodos en subclases para comportamientos distintos, habilitando polimorfismo sin romper el diseño. Todo esto promueve reutilización y mantenibilidad del código.
Clase padre con atributos y métodos comunes.
Clases hijas que heredan y especializan comportamiento.
Override para validar reglas específicas.
Polimorfismo para responder distinto con la misma interfaz.
Herencia múltiple cuando un objeto combina roles.
¿Cómo modelar usuarios con clases que heredan?
Partimos de una clase base Usuario con los datos mínimos: nombre y cédula, y un método común: solicitar_libro. Luego extendemos con Estudiante y Profesor, cada uno con validaciones particulares mediante override del método.
¿Cómo definir la clase base usuario?
Esta clase concentra lo compartido por todos los usuarios del sistema: identidad y la capacidad de solicitar libros.
classUsuario:def__init__(self, nombre, cedula): self.nombre = nombre
self.cedula = cedula
defsolicitar_libro(self, titulo):# Lógica genérica de solicitud para cualquier usuarioreturnf"Solicitud de '{titulo}' registrada para {self.nombre}."
¿Cómo extender con estudiante?
Estudiante hereda de Usuario y agrega atributos propios: libros_prestados, carrera y limite_libros. Con override de solicitar_libro se valida, por ejemplo, que la carrera esté activa y que no se exceda el límite de préstamos.
classEstudiante(Usuario):def__init__(self, nombre, cedula, libros_prestados=0, carrera=None, limite_libros=3):super().__init__(nombre, cedula) self.libros_prestados = libros_prestados
self.carrera = carrera
self.limite_libros = limite_libros
defsolicitar_libro(self, titulo):# override: validación extra para estudiantesifnot self.carrera:return"No se puede prestar: carrera inactiva o no registrada."if self.libros_prestados >= self.limite_libros:return"No se puede prestar: alcanzó el límite de libros."returnsuper().solicitar_libro(titulo)
¿Cómo especializar con profesor?
Profesor también hereda de Usuario, pero su validación es distinta: interesa el departamento y no la carrera. Se vuelve a crear el método con override para cubrir esa regla.
classProfesor(Usuario):def__init__(self, nombre, cedula, departamento=None):super().__init__(nombre, cedula) self.departamento = departamento
defsolicitar_libro(self, titulo):# override: validación para profesoresifnot self.departamento:return"No se puede prestar: departamento no asignado."returnsuper().solicitar_libro(titulo)
¿Cuándo aplicar herencia múltiple y polimorfismo en una biblioteca?
Hay casos en los que un mismo usuario combina roles, por ejemplo, Profesor y Estudiante. La herencia múltiple permite componer ambos comportamientos y, si se requiere, priorizar las funcionalidades del profesor por encima de las del estudiante.
classProfesorEstudiante(Profesor, Estudiante):pass# Se priorizan comportamientos de Profesor al declarar primero esa clase
Relación “es un tipo de” para estructurar jerarquías.
Override para validar reglas por rol sin duplicar código.
Polimorfismo para responder distinto con la misma interfaz.
Herencia múltiple cuando un usuario cumple dos roles y se requiere prioridad.
En la próxima implementación, estos conceptos se aplicarán al sistema de biblioteca. Como reto: identifica posibles jerarquías y cuéntalas en los comentarios.
classAnimal: def __init__(self,edad,color): self.edad= edad self.color= color def nacer(self):print('Este animal a nacido') def hablar(self):print('este animal emite un sonido')classPajaro(Animal): def __init__(self, edad, color, vuelo):super().__init__(edad,color) self.vuelo= vuelo#para resumir def hablar(self): #metodo heredado y modificado print('Pio, Pio') def volar(self, distancia):print(f'cuela como el viento {distancia} metros') #metodo unicopiolin =Pajaro(2,"amarillo",100)piolin.hablar()piolin.volar(100)classPadre: def hablar(self):print('hola')classMadre: def reir(self):print('jaja')classHijo(Padre,Madre): passclass Nieto(Hijo): passgerardo =Nieto()gerardo.reir()print(Nieto.__mro__) #orden de herencia
#esto me sirve para refrescar logicade herencia
🧠HERENCIA EN PYTHON
🌳 1. IDEA PRINCIPAL
La herencia permite que una clase (hija) reutilice código de otra (padre).
Es como un árbol familiar de clases:
lo común se define una vez en la raíz y se comparte hacia abajo.
🟩 Objetivo:
Evitar duplicación
Mantener orden
Reutilizar lógica
Facilitar mantenimiento
Permitir polimorfismo
🔗 2. RELACIÓN “ES UN TIPO DE”
Imagina que cada clase responde a esta pregunta:
¿Es un tipo de...?
💡 Ejemplos:
Estudiante → es un tipo de Usuario
Profesor → es un tipo de Usuario
🧩 Resultado:
Ambos heredan lo esencial, pero pueden comportarse distinto.
⚙️ 3. COMPONENTES CLAVE
🧱 Clase padre (base)
Contiene lo común.
Ejemplo: Usuario
Define atributos y métodos compartidos.
🌱 Clases hijas (derivadas)
Heredan del padre.
Añaden o modifican comportamiento.
✏️ Override (sobrescritura)
Permite cambiar un método sin alterar el original.
🎭 Polimorfismo
Mismo método → diferentes respuestas según la clase.
1. Jerarquía de Tipos de Libros (Más directa con tu código actual)
Crear una clase base Libro y especializarla según el tipo:
Libro (clase base)├── LibroFisico
├── LibroDigital
└── LibroReferencia
Ventajas de esta jerarquía:
LibroReferencia: puede override el método prestar() para que nunca se preste (solo consulta en sala)
LibroDigital: no necesita el atributo disponible porque pueden haber múltiples copias simultáneas
LibroFisico: puede agregar atributos como condicion_fisica, ubicacion_estante
Ejemplo de implementación:
classLibroReferencia(Libro):defprestar(self):returnf"{self.titulo} es material de referencia y solo puede consultarse en biblioteca."classLibroDigital(Libro):def__init__(self, titulo, autor, isbn, formato="PDF", url_descarga=None):super().__init__(titulo, autor, isbn, disponible=True) self.formato = formato
self.url_descarga = url_descarga
defprestar(self):# Override: los libros digitales siempre están disponibles self.__veces_prestado +=1# Necesitarías usar el setterreturnf"{self.titulo} disponible para descarga en formato {self.formato}"```
---## **2. Jerarquía de Usuarios** (Como en el documento)Implementar la jerarquía de usuarios que se describe en tus apuntes:```
Usuario (clase base)├── Estudiante
├── Profesor
└── ProfesorEstudiante (herencia múltiple)
Interacción con tu clase Libro:
classUsuario:def__init__(self, nombre, cedula): self.nombre = nombre
self.cedula = cedula
self.libros_en_prestamo =[]defsolicitar_libro(self, libro):if libro.disponible: resultado = libro.prestar() self.libros_en_prestamo.append(libro)return resultado
returnf"{libro.titulo} no disponible"classEstudiante(Usuario):def__init__(self, nombre, cedula, carrera=None, limite_libros=3):super().__init__(nombre, cedula) self.carrera = carrera
self.limite_libros = limite_libros
defsolicitar_libro(self, libro):# Override con validaciones específicasifnot self.carrera:return"No se puede prestar: carrera inactiva"iflen(self.libros_en_prestamo)>= self.limite_libros:return"Alcanzó el límite de libros"returnsuper().solicitar_libro(libro)```
---## **3. Jerarquía de Materiales Bibliográficos** (Más extensible)Crear una clase base `MaterialBiblioteca` de la cual hereden diferentes materiales:```
MaterialBiblioteca (clase base)├── Libro
├── Revista
├── DVD
└── AudioLibro
```
**Beneficio:** Cada material tiene reglas de préstamo diferentes, pero comparten estructura común.---## **4. Jerarquía por Categoría Académica**```
Libro (clase base actual)├── LibroAcademico (periodo préstamo:15 días)├── LibroFiccion (periodo préstamo:30 días)└── LibroInfantil (periodo préstamo:7 días)
Cada categoría podría tener atributos específicos como dias_prestamo_maximo y diferentes niveles de popularidad.
En el quiz, la pregunta ¿Cómo utilizarías el método init al crear múltiples instancias de una clase en Python?, no estoy de acuerdo con la respuesta correcta, pues creo que todas las instancias de una clase utilizan los mismos parámetros, pero evidentemente, con distintos valores
Estás en lo cierto, sin embargo creo que se refiere a que se pueden crear inits que tengan valores por defecto y así si no lo envias se define sin que lo envies.