# Encapsulamiento (informática)

En la programación orientada a objetos (POO), la encapsulación se refiere a la agrupación de datos con los métodos que operan en esos datos, o la restricción del acceso directo a algunos de los componentes de un objeto. La encapsulación se utiliza para ocultar los valores o el estado de un objeto de datos estructurados dentro de una clase, evitando el acceso directo a ellos por parte de los clientes de una manera que podría exponer detalles de Implementación ocultos o violar la invariancia de estado mantenida por los métodos.
Sin embargo, ocultar datos no es el alcance total de la ocultación de información. David Parnas introdujo por primera vez el concepto de ocultación de información alrededor de 1972. Argumentó que el criterio principal para la modularización del sistema debería referirse a la ocultación de decisiones críticas de diseño. Hizo hincapié en ocultar «decisiones de diseño difíciles o decisiones de diseño que probablemente cambien». Ocultar información de esa manera aísla a los clientes de requerir un conocimiento profundo del diseño para usar un módulo y de los efectos de cambiar esas decisiones.

## Significado

Podríamos decir por tanto que con la encapsulación logramos agrupar datos o restringir el acceso directo a algunos componentes de un objeto, mediante métodos a modo de intermediarios que harán uso de ellos mediante unas reglas definidas. Ayudándonos así por ejemplo a alcanzar otro nivel de la programación orientada a objetos como sería el polimorfismo (no confundir con el polimorfismo en el malware).
El polimorfismo se refiere a la propiedad por la que es posible enviar mensajes sintácticamente iguales a objetos de tipos distintos. El único requisito que deben cumplir los objetos que se utilizan de manera polimórfica es saber responder al mensaje que se les envía.
El ejemplo más claro de encapsulación y polimorfismo sería un programa capaz de calcular las áreas de distintos polígonos, un cliente solo debería de conocer la existencia del método encargado de devolver el área, sin necesidad de preocuparse del proceso interno para calcular las mismas, puesto que el cálculo del área de un cono no se corresponde con la de un rectángulo. Será tarea del programador asegurar la encapsulación para que los métodos que devuelven el área de los distintos objetos de diferentes polígonos respondan de la misma manera, cada uno mediante su propia fórmula matemática de cálculo del área, logrando así el mencionado polimorfismo.
De esta forma además de que el usuario de la clase puede obviar la implementación de los métodos y propiedades para concentrarse solo en cómo usarlos, evita que el usuario pueda cambiar su estado de maneras imprevistas e incontroladas.

### Encapsulación y herencia

Los autores de "Design Patterns" discuten la tensión entre la herencia y la encapsulación y afirman que, en su experiencia, los diseñadores abusan de la herencia. Afirman que la herencia a menudo rompe la encapsulación, dado que la herencia expone una subclase a los detalles de la implementación de su clase padre. Como se describe en el problema del yo-yo, el uso excesivo de la herencia y, por lo tanto, la encapsulación, puede volverse demasiado complicado y difícil de depurar.

## Modificadores de acceso

Los modificadores de acceso son palabras clave que se usan para especificar la accesibilidad declarada de un miembro o un tipo. Depende del lenguaje de programación que se use, pero los más comunes son:
* Default: En el caso del lenguaje Java, los miembros de datos, clase o métodos que no se declaran utilizando ningún modificador de acceso, es decir, que tengan un modificador de acceso predeterminado, solo son accesibles dentro del mismo paquete.
* Public: El acceso público es el nivel de acceso más permisivo. No hay ninguna restricción para el acceso a miembros públicos.
* Protected: Un miembro protegido es accesible dentro de su clase y por parte de instancias de clases derivadas.
* Private: El acceso privado es el nivel de acceso menos permisivo. Los miembros privados solo son accesibles dentro del cuerpo de la clase o el struct en el que se declaran.
* Internal: Solo se puede tener acceso a los tipos internos o los miembros desde los archivos del mismo ensamblado.
* Protected internal: Se puede obtener acceso a un miembro protected internal desde el ensamblado actual o desde tipos que se deriven de la clase contenedora.
* Private protected: Los miembros private protected están accesibles para los tipos que se deriven de la clase contenedora, pero solo desde dentro del ensamblado correspondiente que lo contenga.

## Ejemplos

Un ejemplo de la lógica empleada en pseudocódigo:
Un ejemplo real en el lenguaje de programación C#:
Salida:
* Consola de comandos
* Nombre: Nombre de la persona
* Edad: 00
En caso de intentar acceder directamente a uno de los campos de la clase, saltándonos por tanto la encapsulación:
El propio compilador ya nos avisaría del error con respecto a los modificadores de acceso:
* Error    CS0122   "ClaseEjemplo.nombre' no es accesible debido a su nivel de protección"