En los sistemas de software, la encapsulación se refiere a la agrupación de datos con los mecanismos o métodos que operan sobre ellos. También puede referirse a la limitación del acceso directo a algunos de esos datos, como los componentes de un objeto. [1] Básicamente, la encapsulación evita que el código externo se ocupe del funcionamiento interno de un objeto.
La encapsulación permite a los desarrolladores presentar una interfaz consistente que sea independiente de su implementación interna. Por ejemplo, la encapsulación se puede utilizar para ocultar los valores o el estado de un objeto de datos estructurados dentro de una clase . Esto evita que los clientes accedan directamente a esta información de una manera que podría exponer detalles de implementación ocultos o violar la invariancia de estado mantenida por los métodos.
La encapsulación también alienta a los programadores a colocar todo el código relacionado con un determinado conjunto de datos en la misma clase, lo que lo organiza para que otros programadores puedan comprenderlo fácilmente. La encapsulación es una técnica que fomenta el desacoplamiento .
Todos los sistemas de programación orientada a objetos (POO) admiten la encapsulación, [2] [3] pero la encapsulación no es exclusiva de la POO. Las implementaciones de tipos de datos abstractos , módulos y bibliotecas también ofrecen encapsulación. Los teóricos de los lenguajes de programación han explicado la similitud en términos de tipos existenciales . [4]
En los lenguajes de programación orientados a objetos y otros campos relacionados, la encapsulación se refiere a una de dos nociones relacionadas pero distintas, y a veces a la combinación de ellas: [5] [6]
Algunos investigadores y académicos de lenguajes de programación utilizan el primer significado solo o en combinación con el segundo como una característica distintiva de la programación orientada a objetos , mientras que algunos lenguajes de programación que proporcionan cierres léxicos ven la encapsulación como una característica del lenguaje ortogonal a la orientación a objetos.
La segunda definición refleja que en muchos lenguajes orientados a objetos y otros campos relacionados, los componentes no se ocultan automáticamente y esto se puede anular. Por lo tanto, quienes prefieren la segunda definición definen el ocultamiento de información como un concepto independiente.
Las características de encapsulación están soportadas por clases en la mayoría de los lenguajes orientados a objetos, aunque también existen otras alternativas.
La encapsulación también puede referirse a contener un proceso repetitivo o complejo en una sola unidad para ser invocado. La programación orientada a objetos facilita esto tanto a nivel de método como de clase. Esta definición también es aplicable a la programación procedimental . [10]
Los autores de Design Patterns analizan en profundidad la tensión entre la herencia y la encapsulación y afirman que, según 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 padre. [11] Como se describe en el problema del yo-yo , el uso excesivo de la herencia y, por lo tanto, de la encapsulación, puede volverse demasiado complicado y difícil de depurar.
Según la definición de que la encapsulación "se puede utilizar para ocultar miembros de datos y funciones miembro", la representación interna de un objeto generalmente se oculta fuera de la definición del objeto. Normalmente, solo los métodos propios del objeto pueden inspeccionar o manipular directamente sus campos. Ocultar los elementos internos del objeto protege su integridad al evitar que los usuarios configuren los datos internos del componente en un estado inválido o inconsistente. Un supuesto beneficio de la encapsulación es que puede reducir la complejidad del sistema y, por lo tanto, aumentar la robustez , al permitir que el desarrollador limite las interdependencias entre los componentes del software. [ cita requerida ]
Algunos lenguajes como Smalltalk y Ruby solo permiten el acceso a través de métodos de objeto, pero la mayoría de los demás (por ejemplo, C++ , C# , Delphi o Java [12] ) ofrecen al programador cierto control sobre lo que se oculta, normalmente a través de palabras clave como public
y private
. [8] El estándar ISO C++ se refiere a protected
, private
y public
como " especificadores de acceso " y que no "ocultan ninguna información". El ocultamiento de la información se logra proporcionando una versión compilada del código fuente que se interconecta a través de un archivo de encabezado.
Casi siempre, existe una manera de anular dicha protección, generalmente a través de una API de reflexión (Ruby, Java, C#, etc.), a veces mediante mecanismos como la manipulación de nombres ( Python ) o el uso de palabras clave especiales como en C++. Los sistemas que brindan seguridad basada en capacidadesfriend
a nivel de objeto (que se adhieren al modelo de capacidades de objeto ) son una excepción y garantizan una encapsulación sólida.
Lenguajes como C++ , C# , Java , [12] PHP , Swift y Delphi ofrecen formas de restringir el acceso a los campos de datos.
A continuación se muestra un ejemplo en C# que muestra cómo se puede restringir el acceso a un campo de datos mediante el uso de una private
palabra clave:
clase Programa { clase pública Cuenta { decimal privado _accountBalance = 500.00 m ; público decimal CheckBalance () { return _accountBalance ; } } static void Main ( ) { Cuenta miCuenta = new Cuenta (); decimal miSaldo = miCuenta.VerificarSaldo ( ) ; /* Este método principal puede verificar el saldo a través del método público * "CheckBalance" proporcionado por la clase "Account" * pero no puede manipular el valor de "accountBalance" */ } }
A continuación se muestra un ejemplo en Java :
clase pública Empleado { salario privado BigDecimal = nuevo BigDecimal ( 50000.00 ); público BigDecimal obtenerSalario () { devolver este . salario ; } public static void main ( ) { Empleado e = new Empleado (); BigDecimal sal = e.getSalary ( ); } }
La encapsulación también es posible en lenguajes no orientados a objetos. En C , por ejemplo, se puede declarar una estructura en la API pública a través del archivo de encabezado para un conjunto de funciones que operan sobre un elemento de datos que contiene miembros de datos que no son accesibles para los clientes de la API con la extern
palabra clave. [13]
// Archivo de encabezado "api.h"struct Entity ; // Estructura opaca con miembros ocultos // Funciones API que operan en objetos 'Entidad' extern struct Entity * open_entity ( int id ); extern int process_entity ( struct Entity * info ); extern void close_entity ( struct Entity * info ); // Las palabras clave extern aquí son redundantes, pero no hacen daño. // extern define funciones que se pueden llamar fuera del archivo actual, el comportamiento predeterminado incluso sin la palabra clave
Los clientes llaman a las funciones de la API para asignar, operar y desasignar objetos de un tipo de datos opaco . El contenido de este tipo es conocido y accesible solo para la implementación de las funciones de la API; los clientes no pueden acceder directamente a su contenido. El código fuente de estas funciones define el contenido real de la estructura:
// Archivo de implementación "api.c"#incluir "api.h" struct Entity { int ent_id ; // Número de identificación char ent_name [ 20 ]; // Nombre ... y otros miembros ... }; // Implementaciones de funciones API struct Entity * open_entity ( int id ) { ... } int proceso_entidad ( struct Entidad * info ) { ... } void cerrar_entidad ( struct Entidad * info ) { ... }
A continuación se muestra un ejemplo de Python , que no admite restricciones de acceso a variables. Sin embargo, la convención es que una variable cuyo nombre está precedido por un guión bajo debe considerarse privada. [14]
clase Auto : def __init __ ( self ) - > Ninguno : self._maxspeed = 200 def drive ( self ) -> None : print ( f " La velocidad máxima es { self._maxspeed } ." ) redcar = Car () redcar.drive () # Esto imprimirá 'La velocidad máxima es 200. ' redcar . _maxspeed = 10 redcar . drive () # Esto imprimirá 'La velocidad máxima es 10.'
mecanismos de encapsulación permiten al programador agrupar datos y las subrutinas que operan sobre ellos en un solo lugar, y ocultar detalles irrelevantes a los usuarios de una abstracción.
{{cite book}}
: Mantenimiento CS1: fecha y año ( enlace )