8

He planteado este tema alguna que otra vez en el chat del sitio pero siento que hay mucha diversidad de opiniones y me ha parecido apropiado poner una pregunta en el sitio.

Partiendo de la base de los cuatro pilares de la POO

  • Abstracción
  • Encapsulamiento
  • Herencia
  • Polimorfismo

Creo que a lo que se llama POO en C# no tiene encapsulamiento de atributos.

Encapsular un atributo, según lo que yo estudié, significa dejar los atributos en cuestión como private.

Esto me lleva a pensar que habitualmente se llama programación orientada a objetos a algo que no lo es.

Según lo que he visto siempre, para definir un atributo de clase en c# se hace como

public int number { get; set; };

Al hacer esto estás ignorando uno de los pilares fundamentales de la POO, que es el encapsulamiento de variables.

¿No sería más correcto llamarlo programación orientada a propiedades, o algo así? Ya que, no se privatizan los atributos y estos son accesibles desde cualquier clase, aunque luego sean o no modificables.

Aritzbn
  • 3,024
  • 1
  • 20
  • 48
  • 2
    Ten en cuenta de que ahí se han creado un *getter* y un *setter*, realmente no estás accediendo a number directamente. – Pablo Lozano Jul 18 '19 at 08:10
  • 1
    Yo de toda la vida los atributos los creo private, `public int number { get; set; };` son un getter y un setter no? – Capt.Teach Jul 18 '19 at 08:12

2 Answers2

10

Encapsular un atributo, según lo que yo estudié, significa dejar los atributos en cuestión como private.

No, encapsular significa tener control sobre cómo se ve un objeto a ojos del usuario del mismo. Esto se consigue separando los datos que "necesitan conocerse" externamente de los que "necesitan ocultarse". La Wikipedia lo explica bastante bien (el resaltado es mío):

En programación modular, y más específicamente en programación orientada a objetos, se denomina encapsulamiento al ocultamiento del estado, es decir, de los datos miembro de un objeto de manera que solo se pueda cambiar mediante las operaciones definidas para ese objeto.

Cada objeto está aislado del exterior, es un módulo natural, y la aplicación entera se reduce a un agregado o rompecabezas de objetos. El aislamiento protege a los datos asociados de un objeto contra su modificación por quien no tenga derecho a acceder a ellos, eliminando efectos secundarios e interacciones.

De esta forma el usuario de la clase puede obviar la implementación de los métodos y propiedades para concentrarse solo en cómo usarlos. Por otro lado se evita que el usuario pueda cambiar su estado de maneras imprevistas e incontroladas.

Por lo tanto, publicar datos internos de un objeto no rompe el encapsulamiento, lo que rompe el encapsulamiento es hacerlo sin control o publicar datos internos que el usuario no necesita conocer.

Puede ser más fácil de entender con una analogía:

I magina un coche: la carrocería te oculta los elementos internos como el motor, la batería, la caja de cambios, los ejes, etcétera...

Mmm... me pregunto qué pasará si le pego un lametón a la junta de la trócola.

No necesitas saber que esos elementos están ahí para usar el coche (no necesitas siquiera verlos) lo único que necesitas saber es dónde están los pedales, la palanca de cambios y el contacto.

De hecho, es probable que tú o cualquiera que use el coche tenga la tentación de manipular los elementos que tenga accesibles, con la posibilidad de derivar en un uso incorrecto de los mismos, cuantas más cosas se puedan manipular más probabilidades hay de que sean manipuladas de manera incorrecta.

Marc
  • 5,005
  • 7
  • 17
  • 36
PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82
  • Todo correcto, pero mi punto estaba en si se usa correctamente en la práctica, ya que en muchos ejemplos, suele verse como `public var {get; set; }` ¿esto rompe el encapsulamiento? – Aritzbn Jul 18 '19 at 08:41
  • El concepto "*encapsulamiento de variables*" no existe. El encapsulamiento se refiere a un diseño del objeto completo, no a sus sub-componentes. El objeto no seguiría los principios del encapsulamiento si estuviera haciendo accesibles datos, estados y comportamientos que no deberían ser accesibles. – PaperBirdMaster Jul 18 '19 at 08:44
  • Repito mi duda, ¿definir propiedades como las he expuesto rompe el encapsulamiento dejando accesibles estas propiedades a elementos externos? Aplicando tu analogía ¿Si yo hago `public motor { get; set; }` estoy dejando el motor expuesto como en [este coche](https://img1.cgtrader.com/items/5490/522ffaaab5/ford-1933-hot-wheels-hot-rod-3d-model-max-obj-mtl-3ds-fbx-c4d-lwo-lw-lws.jpg)? – Aritzbn Jul 18 '19 at 08:50
  • 4
    Misma pregunta: Misma respuesta. ¿Rompe el encapsulamiento publicar propiedades? NO si esas propiedades son necesarias para usar el objeto. SI si esas propiedades no son necesarias para usar el objeto. – PaperBirdMaster Jul 18 '19 at 08:59
3

Creo que hay algún tipo de confusión en esto.

Es posible que hayas visto código C# generado en Visual Studio donde public int number { get; set; }; es autogenerado al usar el snippet prop + TAB que te genera el codigo que has puesto quedando en get public y el set private

Si usas el snippet propfull + TAB TAB te genera esto.

private int mivariable;

public int miProp
{
    get { return mivariable;}
    set { mivariable= value;}
}

Entonces yo creo que simplemente has visto codigo autogenerado y que de normal se sigue usando private int miVariable. No se si esto es lo que estabas preguntando. Un saludo

EDIT:

Usando al final este encapsulamiento public int number { get; set; }; Visual Studio crea internamente un private int number

Capt.Teach
  • 1,129
  • 2
  • 12
  • 18
  • 1
    Bueno, he visto respuestas en StackOverflow, yo mismo en el tiempo que llevo con C# un año y medio aprox. genero las variables con `public var { get; set; }` por comodidad y es por eso que me ha surgido la duda, creo que si existe confusión, pero esto va más allá del código autogenerado. – Aritzbn Jul 18 '19 at 08:36
  • 1
    Claro pero Visual Studio crea internamente al final un private var, puede ser que al final el lio venga que en otros sitios se le llama atributos a otra cosa quien sabe jajaja – Capt.Teach Jul 18 '19 at 08:41