Clases y herencia en Python
Al finalizar este tema
Comprenderá qué son las clases, por qué son necesarias, cómo definir una clase para crear objetos y cómo reutilizar código mediante la herencia.
Cuándo es necesario usar clases
Supongamos que desea administrar datos de estudiantes. También podría hacerlo con diccionarios.
student1 = {"name": "Kim Hun", "score": 90}student2 = {"name": "Lee Su", "score": 85}
def get_grade(student): if student["score"] >= 90: return "A" elif student["score"] >= 80: return "B" return "C"El problema surge cuando la escala aumenta. Al añadir funcionalidades como "control de asistencia", "modificar calificaciones" o "agregar materias" para el estudiante, las funciones se dispersan, obligando a buscar constantemente "¿dónde está el código relacionado con el estudiante?".
Las clases agrupan datos (atributos) y funciones (métodos) en una sola unidad.
Definición de clases e instanciación
class Student: def __init__(self, name, score): self.name = name # atributo de instancia self.score = score
def grade(self): if self.score >= 90: return "A" elif self.score >= 80: return "B" return "C"
def introduce(self): return f"{self.name} (grado {self.grade()})"# Creación de instanciass1 = Student("Kim Hun", 90)s2 = Student("Lee Su", 85)
print(s1.introduce()) # Kim Hun (grado A)print(s2.grade()) # Bs2.score = 92 # modificación de puntuaciónprint(s2.grade()) # A__init__es el constructor: se invoca automáticamente cuando se crea una instancia.selfes self: es el medio para acceder a los atributos de esta instancia.- Cuando se llama a
Student("Kim Hun", 90), se ejecuta__init__(self, "Kim Hun", 90).
¿Por qué usar clases?
La misma funcionalidad se puede implementar utilizando funciones y diccionarios. El verdadero valor de las clases reside en reunir en un solo lugar "lo que se puede hacer con estos datos".
# Enfoque funcional: datos y funciones separadosstudent = {"name": "Kim Hoon", "scores": []}add_score(student, 90)get_average(student)get_grade(student)
# Enfoque orientado a objetos: datos y funciones integradosstudent = Student("Kim Hoon")student.add_score(90)student.average()student.grade()Al escribir student., el IDE muestra una lista de "lo que se puede hacer con este objeto". El propio código sirve como documentación.
Herencia: heredar código común
Tanto "estudiante" como "profesor" tienen "nombre" y "afiliación". Coloca la parte común en la clase padre y añade solo las diferencias en las clases derivadas.
class Person: def __init__(self, name, department): self.name = name self.department = department
def introduce(self): return f"{self.name} ({self.department})"
class Student(Person): def __init__(self, name, department, student_id): super().__init__(name, department) # Llamada al constructor padre self.student_id = student_id
def introduce(self): return f"Estudiante {self.name} ({self.student_id})"
class Professor(Person): def __init__(self, name, department, lab): super().__init__(name, department) self.lab = lab
def introduce(self): return f"Profesor {self.name} (Laboratorio de {self.lab})"s = Student("Kim Hoon", "Ciencias de la Vida", "2024-001")p = Professor("Park Jin", "Ciencias de la Vida", "Genómica")
print(s.introduce()) # Estudiante Kim Hoon (2024-001)print(p.introduce()) # Profesor Park Jin (Laboratorio de Genómica)print(s.department) # Ciencias de la Vida — Propiedad heredada de Person- Se llama al constructor de la clase padre mediante
super().__init__(). - Si se define un método con el mismo nombre en la clase hija, este se sobrescribe (redefine).
departmentestá definido enPerson, pero puede ser utilizado tanto porStudentcomo porProfessor.
Resumen clave
| Concepto | Significado |
|---|---|
| Clase | Un plano que agrupa datos (atributos) y funcionalidad (métodos) |
| Instancia | Un objeto real creado a partir del plano (s1 = Student(...)) |
__init__ | Constructor: se ejecuta automáticamente al crear una instancia |
self | Hace referencia a la propia instancia actual |
| Herencia | La clase hija hereda los atributos y métodos de la clase padre |
super() | Llama al método de la clase padre |
| Sobrescritura (Override) | La clase hija redefine el método de la clase padre |
No existe una regla que obligue a "usar siempre" clases. En scripts pequeños, las funciones y los diccionarios son suficientes. Sin embargo, cuando el código crece y es necesario manejar múltiples datos con la misma estructura, las clases son la herramienta más probada para organizar el código.