# Encapsulamiento <!-- Put the link to this slide here so people can follow --> slide: https://hackmd.io/@ichigar/S1Arq9p2F --- * El **encapsulamiento** es la propiedad que permite asegurar que la **información y los métodos de un objeto** están **ocultos** del mundo exterior. * Caso en el que queremos que atributos sean accedidos solo internamente en el objeto. --- ### Tipos de niveles de acceso 1. **Público** * Los datos y los métodos accesibles desde cualquier parte * Nivel más bajo de protección. * Partes del objeto consituyen interfaz 2. **Protegido** * Los datos y métodos no son accesibles externamente. * Accesibles desde clase o suclase --- ### Tipos de niveles de acceso 3. **Privado** * Nivel más alto de protección * Accesibles solo desde la propia clase --- ## Aplicando niveles de acceso * En muchos lenguajes de programación se usan modificadores * Java -> public, protected y private ```java class UniversityStudent { private int id; public string name; ... } ``` * En Python se siguen otros principios --- ### Miembros públicos en Python * **miembros de una clase** -> atributos y métodos * Python miembros públicos por defecto. * Cualquier miembro puede ser accedido desde el exterior --- ```python class Student: school_name = 'XYZ School' # class attribute def __init__(self, name, age): self.name=name # instance attribute self.age=age # instance attribute def show_name(self): return self.name ``` * Podemos acceder a los miembros de la clase e incluso modificar su valor: ```python >>> sebastian = Student("Sebastián", 15) >>> print(sebastian.age) 15 >>> sebastian.name = "Antonio" >>> print(sebastian.show_name()) 'Antonio' ``` --- # Actividad 1 --- ### Miembros privados * Nivel más alto de protección * Miembros solo pueden ser accedidos internamente. * Python no existe un modificador para definir protección * Se sigue el convenido de que el nombre tiene de prefijo doble guión bajo (`__`) --- ```python class Student: __school_name = 'XYZ School' # private class attribute def __init__(self, name, age): self.__name=name # private instance attribute self.__age=age # private instance attribute def __get_age(self): # private method return self.__age ``` * Comprobación ```python >>> std = Student("Bill", 25) >>> std.__school_name AttributeError: 'Student' object has no attribute '__school_name' >>> std.__name AttributeError: 'Student' object has no attribute '__name' >>> std.__get_age() AttributeError: 'Student' object has no attribute '__get_age' ``` * Obtenemos error --- * Cuando Python miembros que empiezan con `__` los enmascara * Son renombrados internamente añadiendo prefijo `_NombreClase`. ```python >>> std = Student("Bill", 25) >>> std.__name AttributeError: 'Student' object has no attribute '__name' # Con el prefijo _Student si podemos acceder a los miembros >>> std._Student__name 'Bill' >>> std._Student__name = 'Steve' >>> std._Student__name 'Steve' >>> std._Student__get_age() 25 ``` --- ### Acceso externo a miembros protegidos * Miembros protegidos no accesibles externamente * Damos acceso de forma controlada * Creamos metodos público que acceda a los miembros privados de la clase. --- * Ejemplo mostrar información privada de estudiante: ```python class Student: __school_name = 'XYZ School' # private class attribute def __init__(self, name, age): self.__name=name # private instance attribute self.__age=age # private instance attribute def __get_age(self): # private method return self.__age def show_student(self): # public method age_info = self.__get_age() # can access private method return f"{self.__name} is {age_info} years old and member of {self.__school_name}" # can access private attributes ``` ```python >>> std = Student("Bill", 25) Bill is 25 years old and member of XYZ School ``` --- # Actividad 2 --- ### Miembros protegidos * Accesibles internamente o desde las clases heredadas (subclases) * Python -> convenio prefijo 1 subrayado (`_`) ```python class Student: _school_name = 'XYZ School' # protected class attribute def __init__(self, name, age): self._name=name # protected instance attribute self._age=age # protected instance attribute def _get_age(self): # protected method return self._age ``` --- * No se realiza ninguna traducción interna * Aunque formalmente miembro es protegido, realmente si es accesible externamente. ```python >>> std = Student("Swati") >>> std._name 'Swati' >>> std._name = 'Dipa' >>> std._name 'Dipa' ``` --- The culture in Python is that names starting with **underscores** mean: **don't use these unless you really know you should** You might choose to begin your **"protected"** methods with underscores. But keep in mind, this is just a **convention**, it doesn't change how the method can be accessed. --- ## Resumiendo * Miembro **privado**: nombre -> prefijo doble subrayado (`__`) * Miembro **protegido**: nombre -> prefijo un subrayado (`_`) * Miembro **público**: nombre no tiene subrayado al principio.
{"metaMigratedAt":"2023-06-16T17:53:40.752Z","metaMigratedFrom":"YAML","title":"PRO-Presentación-POO-Encapsulamiento","breaks":true,"description":"POO Encapsulamiento","slideOptions":"{\"theme\":\"white\",\"transition\":\"fade\",\"center\":true,\"slideNumber\":true,\"spotlight\":{\"enabled\":false}}","contributors":"[{\"id\":\"c266cbca-3d39-40da-b70a-fce5d89de050\",\"add\":11057,\"del\":5570}]"}
    197 views