En la programación orientada a objetos (OOP), 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. [1] La encapsulación se usa 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.
Los métodos de acceso público generalmente se proporcionan en la clase para acceder o modificar el estado de manera más abstracta. En la práctica, a veces se proporcionan métodos (los llamados "captadores" y "definidores" ) para acceder a los valores indirectamente, pero, aunque no necesariamente una violación de la encapsulación abstracta, a menudo se los considera una señal de programación orientada a objetos potencialmente deficiente. (POO) práctica de diseño [2] (un antipatrón ).
Este mecanismo no es exclusivo de la programación orientada a objetos. Las implementaciones de tipos de datos abstractos , por ejemplo, módulos , ofrecen una forma similar de encapsulación. La similitud ha sido explicada por los teóricos del lenguaje de programación en términos de tipos existenciales . [3]
Significado
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 las mismas: [4] [5]
- Un mecanismo de lenguaje para restringir el acceso directo a algunos de los componentes del objeto . [6] [7]
- Una construcción de lenguaje que facilita la agrupación de datos con los métodos (u otras funciones) que operan en esos datos. [1] [8]
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 está motivada por el hecho de que en muchos lenguajes orientados a objetos y otros campos relacionados, los componentes no se ocultan automáticamente y esto puede anularse; por lo tanto, la ocultación de información se define como una noción separada por aquellos que prefieren la segunda definición.
Las características de encapsulación se admiten mediante clases en la mayoría de los lenguajes orientados a objetos, aunque también existen otras alternativas.
Encapsulación y herencia
Los autores de Design Patterns discuten extensamente la tensión entre herencia y 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 padre. [9] 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.
Ocultación de información
Según la definición de que la encapsulación "se puede utilizar para ocultar miembros de datos y funciones de miembros", la representación interna de un objeto generalmente se oculta a la vista fuera de la definición del objeto. Normalmente, solo los métodos propios del objeto pueden inspeccionar o manipular directamente sus campos. Ocultar las partes internas del objeto protege su integridad al evitar que los usuarios establezcan los datos internos del componente en un estado no vá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 otros (por ejemplo, C ++ , C # , Delphi o Java ) ofrecen al programador un grado de control sobre lo que está oculto, generalmente a través de palabras clave como public
y private
. [7] estándar ISO C ++ se refiere a protected
, private
y public
como " especificadores de acceso " y que no lo hacen "ocultar cualquier información". La ocultación de 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, hay una forma de anular dicha protección, generalmente a través de la API de reflexión (Ruby, Java, C #, etc.), a veces mediante un mecanismo como la manipulación de nombres ( Python ) o el uso de palabras clave especiales como friend
en C ++.
Ejemplos de
Restringir campos de datos
Los lenguajes como C ++ , C # , Java , 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 { público de clase Cuenta { privado decimal accountBalance = 500.00 m ; pública decimal CheckBalance () { volver este . accountBalance ; } } static void Main () { Account myAccount = nueva cuenta (); decimal myBalance = myAccount . CheckBalance (); / * 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 :
Empleado de clase pública { salario BigDecimal privado = nuevo BigDecimal ( 50000.00 ); public BigDecimal getSalary () { devuelve esto . salario ; } public static void main () { Empleado e = nuevo 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 en un elemento de datos que contiene miembros de datos que no son accesibles para los clientes de la API con la extern
palabra clave. [10] [11]
// Archivo de encabezado "api.h" Entidad de estructura ; // Estructura opaca con miembros ocultos// Funciones de 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 externas 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 . Los contenidos de este tipo son conocidos y accesibles solo para la implementación de las funciones de la API; los clientes no pueden acceder directamente a sus contenidos. El código fuente de estas funciones define el contenido real de la estructura:
// Archivo de implementación "api.c"#include "api.h" Entidad estructura { 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 process_entity ( struct Entity * info ) { ... }void close_entity ( struct Entity * info ) { ... }
Destrozar nombre
A continuación se muestra un ejemplo de Python , que no admite restricciones de acceso variable. Sin embargo, la convención es que una variable cuyo nombre esté precedido por un guión bajo debe considerarse privada. [12]
class Car : def __init__ ( self ) -> None : self . _maxspeed = 200 def drive ( self ) -> None : print ( f "La velocidad máxima es { self . _maxspeed } ." ) redcar = Coche () redcar . drive () # Esto imprimirá 'La velocidad máxima es 200.'redcar . _maxspeed = 10 redcar . drive () # Esto imprimirá 'La velocidad máxima es 10.'
Ver también
- Herencia (programación orientada a objetos)
- Programación orientada a objetos
- Patrón de diseño de software
- Patrón de fachada
Referencias
- ^ a b Rogers, Wm. Paul (18 de mayo de 2001). "La encapsulación no es ocultar información" . JavaWorld . Consultado el 20 de julio de 2020 .
- ^ Holub, Allen (5 de septiembre de 2003). "Por qué los métodos Getter y Setter son malos" . Info World . JavaWorld . Consultado el 17 de enero de 2021 .
- ^ Pierce 2002 , § 24.2 Abstracción de datos con existenciales
- ^ Scott, Michael Lee (2006). Pragmática del lenguaje de programación (2 ed.). Morgan Kaufmann. pag. 481. ISBN 978-0-12-633951-2.
Los mecanismos de encapsulación permiten al programador agrupar datos y las subrutinas que operan en ellos en un solo lugar, y ocultar detalles irrelevantes a los usuarios de una abstracción.
- ^ Dale, Nell B .; Weems, Chip (2007). Programación y resolución de problemas con Java (2ª ed.). Jones y Bartlett. pag. 396. ISBN 978-0-7637-3402-2.
- ^ Mitchell, John C. (2003). Conceptos en lenguajes de programación . Prensa de la Universidad de Cambridge. pag. 522. ISBN 978-0-521-78098-8.
- ^ a b Pierce, Benjamin (2002). Tipos y lenguajes de programación . Prensa del MIT. pag. 266. ISBN 978-0-262-16209-8.
- ^ Connolly, Thomas M .; Begg, Carolyn E. (2005). "Cap. 25: Introducción a Object DMBS § Conceptos orientados a objetos". Sistemas de bases de datos: un enfoque práctico para el diseño, la implementación y la gestión (4ª ed.). Educación Pearson. pag. 814. ISBN 978-0-321-21025-8.
- ^ Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlissides, John (1994). Patrones de diseño . Addison-Wesley. ISBN 978-0-201-63361-0.
- ^ King, KN (2008). Programación en C: un enfoque moderno (PDF) (2ª ed.). WW Norton & Company. pag. 464. ISBN 978-0393979503. Consultado el 1 de noviembre de 2019 .
- ^ King, Programación de Kim N. C: un enfoque moderno . WW Norton & Company, 2008. Cap. 18, pág. 464, ISBN 0393979504
- ^ Bader, Dan. "El significado de guiones bajos en Python" . Mejore sus habilidades con Python . Consultado el 1 de noviembre de 2019 .