Encapsulation
Nombre:
Correa Escalona Gerardo
Matricula:
2303160
Asignatura:
Programación Orientada a Objetos
Fecha:01/03/2024
#Se crea la clase Employee
class Employee:
#USamos el constructor para inicializar la clase y definimos los
atributos de la clase
def __init__ (self, name, salary, project):
#Se asignan los valores de los argumentos en las instancias
[Link] = name
[Link] = salary
[Link] = project
#Se define el método show que imprimirá el nombre del empleado y su
salario
def show(self):
print("Name:", [Link], 'Salary:', [Link])
#Se define el método work que mostrará el empleo del trabajador
def work(self):
print([Link], "is working on", [Link])
#Se crea el objeto emp de la clase Employee, y se asigna un valor a cada
argumento
emp = Employee('Jessa', 8000, 'NLP')
#Se llaman los métodos creados anteriormente
[Link]()
[Link]()
En este código se crea la Clase Employee, con los atributos nombre, salario y
proyecto. Y se implementa un comportamiento con los métodos work() y show()
que mostrarán información de los empleados(objetos).
#Miembro privado, para definir una variable privada se añaden dos guiones
bajos como prefijo al inicio de la variable
#Miembros privados son accesibles únicamente dentro de la clase
#No es posible acceder a ellos directamente desde los objetos de la clase
#Se crea la clase Employee
class Employee:
#Usamos el constructor para inicializar la clase y definimos los
atributos de la clase
def __init__(self, name, salary):
#Se crea un miembro público
[Link] = name
#Se crea un miembro privado (doble guión bajo)
self.__salary = salary
#Se crea el objeto emp de la clase Employee y se asignan valores a las
variables
emp = Employee('Jessa', 10000)
#Se accede al dato del miembro privado
print('Salary:', emp.__salary)
#Como el salario es un miembro privado, no podemos acceder a él desde fuera
de la clase, por eso marcará un error
#Es posible acceder a miembros privados desde fuera de la clase:
#1.- Creando un método público que acceda a los miembros privados
#2.- Usando "name Mangling"
Este código crea la clase Employee, con un atributo público y uno privado, se crea
un objeto y se asignan valores a las variables de la clase, posteriormente, se
intenta utilizar el miembro privado sin éxito, esto debido a que, no es posible
acceder a este desde fuera de la clase.
#Método público para acceder a miembros privados
#Se crea la clase Employee
class Employee:
#Usamos el constructor para inicializar la clase y definimos los
atributos de la clase
def __init__ (self, name, salary):
#se crea un miembro público
[Link] = name
#Se crea un miembro privado (usando doble guión bajo)
self.__salary = salary
#Se crea un método público "show"
def show(self):
#Imprime la información del empleado
print("Name:", [Link], "Salary:", self.__salary)
#Se crea el objeto emp de la clase Employee
emp = Employee('Jessa', 1000)
#Se llama al método público show de la clase Employee
[Link]()
Este código es muy similar al anterior, sin embargo, aquí se ha creado un método
público que nos permite acceder a los miembros privados de la clase.
#Name mangling para acceder a miembros privados
#Se crea la clase Employee
class Employee:
#Usamos el constructor para inicializar la clase y definimos los
atributos de la clase
def __init__ (self, name, salary):
#se crea un miembro público
[Link] = name
#Se crea un miembro privado
self.__salary = salary
#Creamos el objeto emp de la clase Employee y asginamos valores a los
atributos de la clase
emp = Employee('Jessa', 10000)
#Se imprime el primer atributo del objeto emp (nombre)
print('Name:', [Link])
#Se accede al miembro privado usando name mangling
#(_classname__dataMember, donde classname es la clase actual y datamember es
el nombre del miembro privado)
print('Salary:', emp._Employee__salary)
En este código se utiliza “Name Mangling” para acceder a miembros privados de
una clase, su sintaxis es _classname__dataMember, donde classname es la clase
actual y datamember es el nombre del miembro privado. En este caso también se
logró acceder al miembro privado e imprimir la información del mismo. Se creó la
clase Employee y se usó el constructor __init__ para iniciar la clase y asignar sus
atributos.
#Miembro protegido, es accesible dentro de la clase y también disponible
para las sublclases
#Se define con un guión bajo como prefijo en el nombre de la variable
#Se usan cuando implementas herencia y quieres el acceso a la información
solo a las clases hijas
#Se crea la clase Company
class Company:
#Se usa el constructor para inicializar la clase
def __init__ (self):
#Se crea un miembro protegido(usando guión bajo) y le asignamos
valor predeterminado
self._project = "NLP"
#Se crea la clase hija Company
class Employee (Company):
#inicializamos la clase y creamos un atributo
def __init__ (self, name):
#Se crea un miembro privado
[Link] = name
#Heredamos el miembro protedigo de la clase padre
Company.__init__ (self)
#Se define el método show
def show(self):
#Se imrpime el nombre del empleado que se guarda en el miembro
público
print("Employee name:", [Link])
#Se accede al miembro privado en la clase(hija) Employee (guión
bajo)
print("Working on project" , self._project)
#Se crea el objeto c de la clase Employee
c = Employee("Jessa")
#Se llama al método show de la clase Employee
[Link]()
#Acceso directo a la información del miembro protegido desde el objeto
creado en la clase Employee
print("Project:", c._project)
Este código es un ejemplo del uso de miembros protegidos que se usan cuando
implementas herencia y quieres el acceso a la información solo a las clases hijas.
Primero se crea la clase Company con un miembro protegido y valor
predeterminado. Posteriormente se crea una clase hija Employee con el atributo
name y hereda el atributo de la clase padre Company. Se crea un método en la
clase Employee que mostrará la información del empleado. Se crea un objeto en
la subclase Employee y se llama al método anteriormente creado. Al final se
accede directamente al miembro protegido
#Getters and setters
#En python variables privadas no son campos escondidos como en otros
lenguajes
#Se usan cuando queremos evitar acceso directo a variables privadas
#Añadir validación lógica para definir un valor
#Se crea la clase Student
class Student:
#Inicializamos la clase con el constructor y creamos atributos
def __init__ (self, name, age):
#se crea un miembro público
[Link] = name
#Se crea un miembro privado
self.__age = age
#se crea un método getter
def get_age(self):
return self.__age
#Se crea un método setter
def set_age(self, age):
self.__age = age
#Se crea el objeto stud de la clase Student
stud = Student('Jessa', 14)
#se recupera la edad usando el getter. Donde se pone el nombre del objeto y
el método getter
print("Name:", [Link], stud.get_age())
#Se cambia la edad usando el método setter
stud.set_age(16)
#se recupera la edad usando el getter.
print('Name:', [Link], stud.get_age())
En este código, se puede observar el uso de getters y setters en Python, primero
se crea la clase Student, la inicializa y se crean dos atributos, uno público y uno
privado. Se crean los métodos getter y setter, se crea un objeto de la clase
Student y se asignan valores a los atributos. Se utiliza el método getter para
obtener la edad del objeto stud. Se cambia la edad usando setter y posteriormente
se imprime el valor actualizado.
#Se verá cómo usar encapsulamiento para implementar información escondiendo
y aplicando validación antes de cambiar-
#los valores de los atributos en un objeto.
#Se crea la clase Student
class Student:
#Inicializamos la clase con el constructor y creamos atributos para la
clase
def __init__(self,name,roll_no,age):
#Se crea un miembro público
[Link] = name
#Se crean miembros privados para restringir el acceso
#evita la modificación directa de la información
self.__roll_no = roll_no
self.__age = age
#Se crea un método público que mostrará los detalles del estudiante
def show(self):
print('Student Details:', [Link], self.__roll_no)
#Se crea un método getter para obtener el número de rol
def get_roll_no(self,):
return self.__roll_no
#se crea un método setter para asignar un número de rol
def set_roll_no(self, number):
#Se crea una condición para permitir la modificación de la
información con reglas
if number > 50:
#Si el número de rol es mayor a 50 mostrará un mensaje para
cambiarlo
print("Invalid roll no. Please set correct roll number")
else:
#Si el roll_no es menor a 50, se podrá actualizar la información
self.__roll_no = number
#Se crea el objeto jessa de la clase Student
jessa = Student('Jessa', 10, 15)
#Se llama al método show (antes de modificar la info)
[Link]()
#Se cambia el número de rol usando el método setter
#Sin embargo, al no cumplir la condición para actualizar la info, se
imprimirá el mensaje de la condición
jessa.set_roll_no(120)
#nuevamente se usa setter para actualizar la información, pero esta vez
cumpliendo la condición
jessa.set_roll_no(25)
#Se llama al método show para mostrar la información actualizada
[Link]()
Como en el caso anterior, se utilizará getter y setter, pero esta vez aplicando una
validación para su uso. Se añadió una condición para poder utilizar el método
setter, la cual es que el número de rol debe ser menor a 50, de lo contrario, no
podremos acceder a la información del método privado.
Ventajas de encapsulación
1. Seguridad: La principal ventaja es la seguridad de la información.
Encapsulamiento protege un objeto de un acceso no autorizado. Permite
niveles de acceso protegidos y privados para prevenir modificaciones
accidentales.
2. Ocultamiento de datos: El usuario no estaría sabiendo que pasa detrás de
escena. Ellos solo sabrían que, para modificar información de un atributo,
tienen que llamar al método setter. Para leer la información, llamarán al
método getter. Pero lo que estos métodos hacen está escondido para ellos.
3. Simplicidad: Simplifica el mantenimiento de la aplicación manteniendo las
clases separadas y previniéndolas de emparejarlas fuertemente con otras.
4. Estética: Grupo de datos y métodos dentro de una clase hacen el código
mas entendible y sostenible.