Esto permite heredar attributos o funciones ya creadas por un clase "padre/madre", i.e., a parent class
.
Esto permite escribir subclasses que permitan recoger toda la funcionalidad de la parent class
y además, añadir nuevas funcionalidades que no afecten a la parent class
class Empleados:
tasa_incremento_salarial = 1.1
num_de_emps = 0
def __init__(self, nombre, apellido, salario):
self.nombre = nombre
self.apellido = apellido
self.salario = salario
self.email = nombre + "." + apellido + "@emp.com"
Empleados.num_de_emps += 1
def nombre_completo(self):
print(f"{self.nombre} {self.apellido}")
def incremento_salarial(self):
self.salario = int(self.salario * self.tasa_incremento_salarial)
Vamos a suponer que ahora queremos crear dos tipos de empleados: los que trabajan en planta y los que trabajan en la oficina.
Todos tienen un elemento comun definido por su nombre, apellido, salario e email, que ya lo define la clase Empleados
Por tanto, podemos, en las subclasses de trabajdores en planta u oficina podemos heredar estos atributos de la parent class.
class Empleado_Planta(Empleados):
pass
Veamos que, solamente poner esto, genera atributos
empP_1 = Empleado_Planta("Daniel", "Miles", 100000)
empP_2 = Empleado_Planta("Ines", "Gonzalez", 150000)
print(Empleados.tasa_incremento_salarial)
print(empP_1.tasa_incremento_salarial)
empP_1.nombre_completo()
Python utiliza el Scope para buscar la informacion: primero va al local
, y no encuentra; luego va al enclosing
, y encuentra la información.
Aquí, a esto se le llama: Method resolution order. Para verlo, utilizamos help()
help(Empleado_Planta)
Vamos a individualizar las tasas de incremento salarial.
Pero antes, veamos como podemos afectarlas directamente en los atributos
print(empP_1.salario)
empP_1.incremento_salarial()
print(empP_1.salario)
print(empP_1.salario)
empP_1.tasa_incremento_salarial = 1.5
empP_1.incremento_salarial()
print(empP_1.salario)
Peor esto podriamos hacerlo dentro de la subclass.
class Empleado_Planta(Empleados):
tasa_incremento_salarial = 1.75
empP_1 = Empleado_Planta("Daniel", "Miles", 100000)
empP_2 = Empleado_Planta("Ines", "Gonzalez", 150000)
print(empP_1.tasa_incremento_salarial)
print(empP_2.tasa_incremento_salarial)
Lo más usual es usar las subclases para añadir elementos diferenciadores.
Por ejemplo, si queremos pasar la tarea que realiza en planta, esto es algo específico de los trabajadores de planta.
Entonces, vamos a tener que añadir un __init__()
method
class Empleado_Planta(Empleados):
tasa_incremento_salarial = 1.75
num_de_emps_planta = 0
def __init__(self, nombre, apellido, salario, tarea):
#super() va a pasar al parent class la informacion
super().__init__(nombre, apellido, salario)
self.tarea = tarea
Empleado_Planta.num_de_emps_planta += 1
empP_1 = Empleado_Planta("Daniel", "Miles", 100000, "Limpieza")
empP_2 = Empleado_Planta("Ines", "Gonzalez", 150000, "Maquinas")
empP_1.tarea
empP_2.email
Vamos a crear una clase para las jefas de planta donde nos interesara saber cuandos empleados tienen a su cargo
class Jefa_Planta(Empleados):
def __init__(self, nombre, apellido, salario, empleados = None ):
#super() va a pasar al parent class la informacion
super().__init__(nombre, apellido, salario)
if self.empleados == None:
self.empleados = []
else:
self.empleados = empleados
Importante: nunca hay que pasar objetos mutables as default arguments (lo vimos o lo veremos.)
Ahora crearemos altas y bajas de empleados en esta sublace
class Jefa_Planta(Empleados):
def __init__(self, nombre, apellido, salario, empleados = None ):
#super() va a pasar al parent class la informacion
super().__init__(nombre, apellido, salario)
if empleados == None:
self.empleados = []
else:
self.empleados = empleados
#Altas
def alta_emp(self, emp):
if emp not in self.empleados:
self.empleados.append(emp)
#Bajas
def baja_emp(self, emp):
if emp in self.empleados:
self.empleados.remove(emp)
#Imprimir lista de empleados
def print_emp(self):
for emp in self.empleados:
print(f"{emp.nombre_completo()}")
empP_1 = Empleado_Planta("Daniel", "Miles", 100000, "Limpieza")
jp = Jefa_Planta("Maria", "Gonz", "10",[empP_1])
empP_2 = Empleado_Planta("Juan", "Miles", 100000, "Limpieza")
jp.alta_emp(empP_2)
isinstance
: object is an instance of a class
issubclass
: object is an instance of a subclass
isinstance(jp, Empleados)
isinstance(jp, Empleados)
isinstance(jp, Empleado_Planta)
issubclass(Empleado_Planta, Empleados)