¿Por qué necesitamos variables privadas?


210

¿Por qué necesitamos variables privadas en las clases?

Cada libro sobre programación que he leído dice que esta es una variable privada, así es como la define, pero se detiene allí.

La redacción de estas explicaciones siempre me pareció que realmente tenemos una crisis de confianza en nuestra profesión. Las explicaciones siempre sonaban como si otros programadores intentaran estropear nuestro código. Sin embargo, hay muchos lenguajes de programación que no tienen variables privadas.

  1. ¿Qué ayudan a prevenir las variables privadas?

  2. ¿Cómo decide si una propiedad en particular debe ser privada o no? Si por defecto todos los campos DEBEN ser privados, ¿por qué hay miembros de datos públicos en una clase?

  3. ¿En qué circunstancias debe hacerse pública una variable?


99
Su pregunta suena muy independiente del lenguaje, pero la ha etiquetado como java y c ++. Si está interesado en perspectivas desde fuera de esos dos idiomas, probablemente debería decirlo.
James

8
Para el registro, la creación de un método privado no aumenta la "seguridad". Otras partes de su aplicación aún pueden acceder a miembros privados mediante la reflexión.
kba

3
El uso y la diferencia de las variables públicas y privadas, y por qué las tenemos, solo pueden entenderse en el contexto de los principios generales orientados a objetos. No se puede entender por separado. Probablemente necesite verlo desde esa perspectiva, las cosas pueden aclararse.
Nazar Merza

1
posible duplicado de cuándo se justifican los
getters

3
Si atrapa a alguien que usa el cinturón de seguridad en su automóvil, debe quitarle su licencia de conducir, ya que obviamente no confían en sus propias habilidades para conducir.
gnasher729

Respuestas:


307

No es tanto una cuestión de confianza, sino más bien una cuestión de gestión de la complejidad.

Se puede acceder a un miembro público desde fuera de la clase, lo que por consideraciones prácticas significa "potencialmente en cualquier lugar". Si algo sale mal en un campo público, el culpable puede estar en cualquier lugar y, por lo tanto, para rastrear el error, es posible que tenga que mirar una gran cantidad de código.

A un miembro privado, por el contrario, solo se puede acceder desde dentro de la misma clase, por lo que si algo sale mal, generalmente solo hay un archivo fuente para mirar. Si tiene un millón de líneas de código en su proyecto, pero sus clases se mantienen pequeñas, esto puede reducir su esfuerzo de seguimiento de errores en un factor de 1000.

Otra ventaja está relacionada con el concepto de 'acoplamiento'. Un miembro del público mde una clase Aque se utiliza por otra clase Bintroduce una dependencia: si cambia men A, también hay que comprobar los usos de men B. Peor aún, nada en la clase Ale dice dónde mse está utilizando, por lo que nuevamente debe buscar en toda la base de código; si está escribiendo una biblioteca, incluso debe asegurarse de que el código esté afuerasu proyecto no se rompe debido a su cambio. En la práctica, las bibliotecas tienden a seguir con sus firmas de métodos originales el mayor tiempo posible, sin importar cuán doloroso, y luego introducen un bloque de cambios importantes con una actualización de la versión principal. Con los miembros privados, por el contrario, puede excluir las dependencias de inmediato: no se puede acceder a ellas desde afuera, por lo que todas las dependencias están contenidas dentro de la clase.

En este contexto, "otros programadores" incluyen su yo futuro y pasado. Es probable que ahora sepa que no debe hacer esto X con su variable Y, pero seguramente habrá olvidado tres meses más adelante cuando un cliente necesita urgentemente que implemente alguna función, y se pregunta por qué se rompe X Y de maneras oscuras.

Entonces, en cuanto a cuándo debería hacer las cosas privadas: diría que haga que todo sea privado por defecto, y luego exponga solo aquellas partes que absolutamente tienen que ser públicas. Cuanto más puedas hacer privado, mejor.


24
+1 para llegar al meollo del problema, aunque personalmente encontré que mi código era más fácil de mantener cuando dejé de pasar por los aros solo para asegurarme de que una variable de uso frecuente se mantenga privada. Seguro que puede aparecer un error en el futuro, pero hay 60 líneas de código menos para filtrar y menos variables y funciones para arrancar;)
Jeffrey Sweeney

48
El santo grial de la informática moderna es mantener baja la complejidad.

1
Siempre me gusta decir que parte de la depuración no es solo conducir directamente hacia "lo que salió mal", sino tomar el proceso indirecto de descubrir "lo que no salió mal" y enfocar mi investigación en lo que queda. Si puedo conseguir que el compilador me ayude con herramientas como variables privadas para definir "lo que no puede haber ocurrido", eso me ahorra mucho tiempo. Solo en los raros casos en que demuestre que lo que salió mal no puede haber ocurrido, tengo que profundizar en las suposiciones más aterradoras, como tal vez un desbordamiento del búfer que sobrescribe mis datos privados.
Cort Ammon

2
Exactamente eso. Cuando las personas escuchan "ocultar información", piensan que deberían usar variables privadas para cosas como claves de cifrado, credenciales de bases de datos, etc.
Wayne Werner

2
@AdamZerner vea "Tell, don't ask" ( martinfowler.com/bliki/TellDontAsk.html ) acerca de tener getters / setters en primer lugar, pero de lo contrario sí, porque debería ser libre de cambiar la representación interna del valor en cualquier momento tú deseas. Como siempre, hay excepciones ... (por ejemplo, DTO)
doble, el

111

Las variables privadas ayudan a evitar que las personas dependan de ciertas partes de su código. Por ejemplo, supongamos que desea implementar alguna estructura de datos. Desea que los usuarios de su estructura de datos no se preocupen por cómo la implementó, sino que simplemente utilicen la implementación a través de su interfaz bien definida. La razón es que si nadie depende de su implementación, puede cambiarla cuando lo desee. Por ejemplo, puede cambiar la implementación del back-end para mejorar el rendimiento. Cualquier otro desarrollador que dependiera de sus implementaciones se romperá, mientras que los usuarios de la interfaz estarán bien. Tener la flexibilidad de cambiar las implementaciones sin afectar a los usuarios de la clase es un gran beneficio que le proporciona el uso de variables privadas (y, más ampliamente, la encapsulación ).

Además, no es realmente una "crisis de confianza". Si hace pública una pieza de datos, no puede asegurarse de que nadie dependa de ella. A menudo es muy conveniente depender de alguna variable específica de implementación, en lugar de pasar por la interfaz pública, especialmente en el plazo de un plazo. Además, los desarrolladores no siempre se darán cuenta de que dependen de algo que pueda cambiar.

Así que espero que responda a sus otras preguntas. Todos los detalles de su implementación deben ser privados, y la parte pública debe ser una interfaz pequeña, concisa y bien definida para usar su clase.


24
En mi opinión, también se trata de la comunicación entre el autor de la biblioteca y el consumidor de la biblioteca. La interfaz pública es como "use esto" y las privadas como "no use eso", excepto que en Java, realmente no puede usarlo por accidente si lo hace privado, por lo que es más seguro y claro de esa manera.
chakrit

55
@chakrit y otros: tenga en cuenta que aquellos que realmente están dispuestos a usar sus campos y métodos privados pueden hacerlo (a través de la reflexión). privatees menor que "no destinado principalmente a la seguridad", no proporciona "seguridad" para hablar. Es solo una pista fuerte (entregada a través del compilador) para no acceder a ella.

@delnan nota la frase "por accidente", sí, tal vez debería ser más claro al respecto.
chakrit

@chakrit Sí, no quise decir que estabas equivocado. Solo quería promover ese punto.

1
@delnan: los campos privados proporcionan, en algunos idiomas, ciertas formas de seguridad. Por ejemplo, vea la respuesta de Eric Lippert a ¿Los niveles de acceso y modificadores (privados, sellados, etc.) tienen un propósito de seguridad en C #? .
Brian

25

La palabra clave aquí es Encapsulación . En OOP, desea utilizar variables privadas para imponer la encapsulación adecuada de sus objetos / clases.

Mientras que otros programadores no están dispuestos a atraparte, interactúan con tu código. Si no hace que una variable sea privada, bien pueden referirse a ella en su propio código sin querer hacer ningún daño. Sin embargo, si necesita volver a su clase y cambiar algo, ya no sabe quién usa qué variable y dónde. El objetivo de la encapsulación es hacer explícita la interfaz externa de la clase para que sepa que estos métodos (típicamente) podrían haber sido utilizados por otros.

  1. Por lo tanto, las variables privadas aseguran que la variable correspondiente permanezca solo en la clase definitoria. Si necesita cambiarlo, el cambio es local para la clase misma.

  2. En lanugages tradicionales como C ++ o Java, usualmente haces que todo sea privado y solo accesible por getters y setters correspondientes. No hay necesidad de decidir mucho realmente.

  3. A veces, f.ex. En una estructura C ++, necesita una clase solo como una forma de agrupar varias cosas. Por ejemplo, considere una clase de Vector que solo tiene un atributo xy un yatributo. En esos casos, puede permitir el acceso directo a estos atributos declarándolos públicos. En particular, no debe importarle si algún código externo modifica un objeto de su clase escribiendo directamente nuevos valores en xo y.

Como punto adicional, tenga en cuenta que este asunto se considera ligeramente diferente en otros idiomas. Por ejemplo, los lenguajes fuertemente arraigados en la programación funcional enfatizan la inmutabilidad de los datos, es decir, los valores de los datos no se pueden cambiar en absoluto. En tales casos, no tiene que preocuparse por lo que otros programadores (o más bien su código) hagan con sus datos. Simplemente no pueden hacer nada que pueda afectar su código, porque todos los datos son inmutables.

En esos idiomas, por lo tanto, obtienes algo llamado principio de acceso uniforme , donde deliberadamente no se distinguen métodos como getters y setters, sino que proporcionan acceso directo a la variable / función. Entonces puede decir que las declaraciones privadas son mucho más populares en los escenarios orientados a objetos.

Esto también muestra cómo ampliar su conocimiento para incluir otros campos le hace ver los conceptos existentes de una manera completamente nueva.


1
+1 "Mientras que otros programadores no quieren atraparte, interactúan con tu código". Los programadores que usan su código no son intrínsecamente malos. Al usar variables privadas, se asegura de que ellas (y usted, en el futuro) no se lastimen con el código. También le ayuda a diseñar una mejor API y documentarla.
szalski

7

Las variables privadas aseguran que las referencias posteriores fuera del alcance de un objeto o función no afectarán inadvertidamente a otras variables. Para proyectos de programación grandes, esto puede ayudar a evitar muchos problemas interesantes (que el compilador no suele detectar).

Por ejemplo, los lenguajes prototípicos como Javascript pueden permitir a los usuarios enyesar las variables como mejor les parezca:

function SomeObject() {
    this.a = 2; //Public (well, actually protected) variable

    this.showA = function() {
        alert(this.a);
    }
}

//Some lines down...

var obj = new SomeObject();
obj.a = 3;
obj.showA(); //Will alert 3. Uh oh!

Si esa variable fuera privada, no se podría cambiar desde el exterior:

function SomeObject() {
    var a = 2; //Private variable

    this.showA = function() {
        alert(a);
    }
}

//Some lines down...

var obj = new SomeObject();
obj.a = 3;
obj.showA(); //Will alert 2

Dicho esto, no todas las variables deben ser privadas y el uso excesivo de variables privadas puede hacer que el código sea más engorroso. Los campos triviales que no afectan seriamente un objeto no necesitan métodos get()ni set()métodos.

Las variables privadas también facilitan la expansión del código en el futuro, sin depender de una gran cantidad de documentación sobre lo que hacen las muchas variables públicas. Existe una menor amenaza de romper accidentalmente la funcionalidad si se pueden sobrescribir menos variables.

Las variables públicas deben usarse cuando un objeto / función accederá a otros objetos / funciones, ya que, por regla general, las variables privadas no pueden hacer esto. Puede tener desde unas pocas hasta varias variables públicas, y no es malo usarlas si se usan correctamente.


No es obvio por qué alertar a 3 sería un "¡uh oh!" en este caso. Tal vez eso es lo que el programador quería que sucediera.
Immibis

@immibis Tal vez, y tal vez debería haber elaborado más en la respuesta. Pero el acceso a las propiedades puede abrir la puerta para violar algunos principios de OOP, como el principio de abierto-cerrado o LoD, ya que potencialmente está exponiendo los detalles de implementación. por supuesto, depende de cuál sea exactamente la propiedad. La mayoría de los lenguajes usan objetos como referencias, y cuando las referencias de objetos se pasan y otros desarrolladores cambian silenciosamente sus propiedades, puede ser REALMENTE difícil de depurar. En mi opinión, es mucho más fácil y ampliable trabajar con métodos si tiene una instancia de clase.
Jeffrey Sweeney

7

Hay algunas buenas respuestas que mencionan los beneficios para futuros mantenedores y usuarios de una clase. Sin embargo, también hay beneficios en el diseño original. Proporciona un punto de demarcación claro entre cuándo su objetivo es facilitar las cosas a usted mismo y cuándo su objetivo es facilitar las cosas al usuario de la clase. Cuando elige entre público y privado, le indica a su cerebro que cambie a un modo u otro, y termina con una API mejor.

No es que los idiomas sin privacidad hagan imposible tal diseño, solo que sea menos probable. En lugar de que se les pida que escriban algo así foo.getBar(), las personas se inclinan a pensar que no es necesario un captador, porque es más fácil de escribir foo.bar, pero luego esa decisión no se revisa cuando luego terminas con monstruosidades más largas como obj.container[baz].foo.bar. Los programadores que nunca han trabajado en un lenguaje más estricto pueden ni siquiera ver qué hay de malo en eso.

Es por eso que en idiomas sin privacidad las personas a menudo adoptan estándares de nombres que lo simulan, como anteponer un guión bajo a todos los miembros "privados". Es una señal útil incluso cuando el idioma no lo impone.


3

Todas las variables deben ser privadas a menos que sea absolutamente necesario que sean públicas (que casi nunca es así, debe usar propiedades / getters y setters).

Las variables proporcionan en gran medida el estado del objeto, y las variables privadas evitan que otros entren y cambien el estado del objeto.


55
Una vista demasiado estrecha del tema. Hay casos en los que el acceso al campo público está garantizado, incluso preferido
Roland Tepp

Ciertamente, se pueden diseñar objetos cuyo estado no se puede cambiar (objetos inmutables), pero esta no es una regla general aplicada a todas las clases. En mi experiencia, la mayoría de los objetos hacen que sea muy fácil para otros cambiar el estado del objeto.
David K

1
@DavidK Quizás lo que bbb quiso decir es que "las variables privadas evitan que otros entren y cambien indiscriminadamente el estado del objeto". Los métodos públicos pueden cambiar el estado privado del objeto, pero solo en formas que sean necesarias y consistentes para el funcionamiento del objeto.
Max Nanasy

@Max Nanasy: Sí, uno puede controlar cómo se cambia el estado cuando se ofrecen solo métodos en la interfaz pública. Por ejemplo, puede haber una relación entre los miembros que debe satisfacerse para que el objeto sea "autoconsistente", y puede permitir que un estado autoconsistente se cambie solo a otro estado autoconsistente. Si todas esas variables son públicas, entonces no puede aplicar esto. Pero también puede haber objetos en los que no desea permitir ningún cambio, por lo que es importante aclarar de qué cosas estamos hablando.
David K

2
  • ¿Qué ayudan a prevenir las variables privadas?

Se trata de dejar en claro qué propiedades y métodos son la interfaz y cuáles son realmente la funcionalidad principal. Los métodos / propiedades públicos son sobre otro código, a menudo el código de otro desarrollador que usa sus objetos. Nunca he trabajado en equipos de más de 100 en el mismo proyecto, pero en mi experiencia de quizás equipos de 3-5 con hasta 20 otros desarrolladores que usan cosas que he escrito, las otras preocupaciones parecen tontas.

Nota: Soy principalmente un desarrollador de JavaScript. Generalmente no me preocupa que otros desarrolladores vean mi código, y opero con plena conciencia de que simplemente podrían redefinir mis cosas en cualquier momento. Supongo que son lo suficientemente competentes como para saber lo que están haciendo primero. De lo contrario, es poco probable que esté trabajando en un equipo que no use el control de fuente.

  • ¿Cómo decide si un conjunto particular de propiedades debe ser privado o no? Si por defecto todos los campos DEBEN ser privados, ¿por qué hay miembros de datos públicos en una clase?

Solía ​​pensar que era una tontería poner captadores y colocadores en propiedades privadas cuando realmente no realizaba ningún tipo de validación u otro tratamiento especial de la propiedad que se establecería. Todavía no creo que sea siempre necesario, pero cuando se trata de gran escala, alta complejidad, pero lo más importante es que muchos otros desarrolladores que confían en que sus objetos se comporten de manera consistente, puede ser útil hacer las cosas de una manera De manera consistente y uniforme. Cuando la gente ve métodos llamados getThatysetThat, saben exactamente cuáles son las intenciones y pueden escribir sus objetos para interactuar con los suyos con la expectativa de que siempre obtendrán tomates en lugar de tomates. Si no lo hacen, saben que su objeto les está dando algo que probablemente no debería, lo que significa que está permitiendo que otro objeto haga algo con esos datos que probablemente no debería. Puede controlar eso cuando surja la necesidad.

La otra gran ventaja es que es más fácil hacer que sus objetos entreguen o interpreten valores de manera diferente de un captador o definidor basado en algún tipo de contexto de estado variable. Debido a que están accediendo a sus cosas con un método, es mucho más fácil cambiar la forma en que su objeto funciona más adelante sin romper otro código que dependa de él. El principio importante es que solo su objeto realmente cambia los datos de los que lo ha hecho responsable. Esto es particularmente importante para mantener su código débilmente acoplado, lo cual es una gran victoria en términos de portabilidad y facilidad de modificación.

  • ¿En qué circunstancias debe hacerse pública una variable?

Con las funciones de primera clase (puede pasar las funciones como argumentos), no puedo pensar en muchas buenas razones, aparte de que no es muy necesario hacerlo en proyectos de menor escala. Sin él, supongo que podría tener miembros que están siendo procesados ​​en gran medida y regularmente por otros objetos en la medida en que parece un poco difícil llamar constantemente a get y sets en un objeto que realmente no toca esos datos en sí, pero eso en en sí mismo me haría preguntarme por qué el objeto fue responsable de esos datos. En términos generales, me gustaría volver a examinar mi arquitectura en busca de fallas antes de decidir que una propiedad de datos públicos es necesaria. En mi opinión, no hay nada de malo en que un idioma te permita hacer algo que generalmente es una mala idea. Algunos idiomas no están de acuerdo.


En mi humilde opinión, no hay nada particularmente malo en tener una clase pública cuyo único propósito es exponer las variables públicas. De hecho, la JVM tiene una serie de clases incorporadas para tal fin: int[], double[], Object[], etc. Uno debe, sin embargo, ser muy cuidadosos acerca de cómo se expone a instancias de una clase tal. El significado de void CopyLocationTo(Point p);[aceptar a Pointde la persona que llama] es más claro que Point location(), ya que no está claro qué efecto Point pt = foo.location(); pt.x ++;tendrá en la ubicación de foo.
supercat

2

Vea esta publicación mía a una pregunta relacionada sobre SO .

En resumen, el alcance variable le permite mostrar a los consumidores de su código con lo que deberían y no deberían estar jugando. Una variable privada puede contener datos que han sido "examinados" mediante el uso de un establecedor de propiedades o un método de procesamiento para garantizar que todo el objeto esté en estado coherente. Cambiar el valor de la variable privada directamente puede hacer que el objeto se vuelva inconsistente. Al hacerlo privado, alguien tiene que trabajar muy duro y tener permisos de tiempo de ejecución realmente altos para poder cambiarlo.

El alcance adecuado del miembro es, por lo tanto, clave en el código de autodocumentación.


2

Voy a hablar sobre el valor de la encapsulación desde una perspectiva diferente usando un ejemplo real. Hace bastante tiempo (principios de los 80) se escribió un juego para Radio Shack Color Computer llamado Dungeons of Daggorath. Hace algunos años, Richard Hunerlach lo transfirió de una lista de ensambladores de papel a C / C ++ ( http://mspencer.net/daggorath/dodpcp.html ). Algún tiempo después, obtuve el código y comencé a refactorizarlo para proporcionar una mejor encapsulación ( http://dbp-consulting.com/stuff/ ).

El código ya se incluyó en diferentes objetos para manejar la programación, el video, la entrada del usuario, la creación de mazmorras, los monstruos, etc., pero definitivamente se podría decir que fue portado desde el ensamblador. Mi mayor tarea fue aumentar la encapsulación. Con eso me refiero a obtener diferentes partes del código para sacar sus narices de los negocios del otro. Había muchos lugares, por ejemplo, que cambiarían las variables de video directamente para tener algún efecto. Algunos lo hicieron con verificación de errores, otros no, algunos tenían ideas muy diferentes de lo que significaba cambiar eso. Hubo mucha duplicación de código. En cambio, la sección de video necesitaba tener una interfaz para realizar las tareas deseadas, y el código para hacerlo podría estar todo en un solo lugar, una idea, un lugar para depurar. Ese tipo de cosas era rampante.

Cuando el código comenzó a ser descifrado, los errores que ni siquiera habían sido diagnosticados desaparecieron. El código se hizo de mayor calidad. Cada tarea se convirtió en responsabilidad de un lugar en el código y solo había un lugar para hacerlo bien. (Todavía encuentro más cada vez que hago otro pase a través del código).

Todo lo que se ve sobre su código es su interfaz. Si quieres decir que sea o no. Si limita la visibilidad tanto como sea posible, no se sentirá tentado a colocar el código en el lugar incorrecto más adelante. Hace obvio qué parte del código es responsable de qué datos. Crea un diseño mejor, más limpio, más simple y más elegante.

Si hace que un objeto sea responsable de sus propios datos y proporciona interfaces a todos los demás que necesitan que algo suceda, su código se vuelve MUCHO más simple. Simplemente se cae. Tienes pequeñas rutinas simples que solo hacen una cosa. Menos complejidad == menos errores.


El duro equilibrio entre "la libertad de nuestros usuarios de la biblioteca" y "menos problemas para nosotros". Estoy empezando a creer que la encapsulación es mejor en el sentido de que evitaré errores en mi propia codificación, y ayudaré a los usuarios finales a prevenir errores también. Pero la falta de libertad también puede simplemente dejarlos de lado, buscando alternativas ... Puede que la codificación aún no se use pero las funcionalidades previstas a través de métodos públicos pueden ayudar a equilibrar eso, pero exige más tiempo.
Acuario Power

Lástima que la versión refactorizada no esté en github ...
jmoreno

2

No tiene nada que ver con la confianza o el miedo a los ataques, se trata únicamente de encapsulación, no de forzar información innecesaria sobre el usuario de la clase.

Considere las constantes privadas: no deben contener valores secretos (deben almacenarse en otro lugar), no pueden cambiarse, no necesitan pasarse a su clase (de lo contrario, deberían ser públicos). El único uso posible para ellos es como constantes en OTRAS clases. Pero si hace eso, esas clases ahora dependen de su clase, para hacer un trabajo que no está relacionado con su clase. Si cambia la constante, otras clases podrían romperse. Eso es malo desde ambos lados: como escritor de su clase, desea que la libertad cambie tanto como sea posible, y no quiere preocuparse por cosas que están fuera de su control. Un consumidor de su clase quiere poder depender de los detalles expuestos de su clase, sin preocuparse de que lo cambie y rompa su código.

Un consumidor de su clase quiere saber todo lo necesario para INTERACTUAR con su clase, y no quiere saber nada acerca de su clase que no cambie la forma en que lo hacen: son trivias inútiles. Si ha utilizado un lenguaje con reflexión, ¿con qué frecuencia lo ha utilizado para aprender no cómo una clase hace algo o dónde arroja una excepción inesperadamente, sino simplemente el nombre de los campos y métodos privados? Estoy apostando nunca. Porque no tienes uso para ese conocimiento.


1

El concepto OOP tiene herencia tiene una de sus características (Java o C ++). Entonces, si vamos a heredar (lo que significa que vamos a acceder a las variables de la clase heredada), existe la posibilidad de afectar esas variables. Entonces, tenemos que decidir si las variables se pueden cambiar o no.

Solo para este propósito, estamos utilizando modificadores de acceso en OOP. Uno de los modificadores es privado, lo que significa que solo esa clase puede acceder a él. Cualquier otra clase no puede afectar esas variables.

Como sabemos, protegido significa que la clase que va a heredar puede acceder a él.

Por qué hay un concepto modificador en OOP, se debe a estos motivos (cualquier clase puede acceder a otras variables de clase utilizando el concepto OOP). Si no hay un concepto modificador, significa que habría sido difícil al heredar clases o al usar otros conceptos OOP.


1

Como han dicho otros, las variables privadas son buenas para evitar usos erróneos que llevan al objeto a un estado inconsistente y a errores difíciles de rastrear y excepciones imprevistas.

Pero, por otro lado, lo que los demás han ignorado en su mayor parte es sobre los campos protegidos.

Una subclase extendida tendrá acceso completo a los campos protegidos, haciendo que el objeto sea tan frágil como si dichos campos fueran públicos, pero esa fragilidad se limita a la clase extendida por sí misma (a menos que exponga aún más dichos campos).

Por lo tanto, los campos públicos son difíciles de considerar buenos, y hasta la fecha, la única razón para usarlos es para las clases utilizadas como parámetro de configuración (una clase muy simple con muchos campos y sin lógica, por lo que esa clase se pasa como un parámetro solo a algún método).

Pero, por otro lado, los campos privados reducen la flexibilidad de su código a otros usuarios.

Flexibilidad frente a problemas, pros y contras:

Los objetos instanciados por su código en la clase vainilla con campos protegidos son seguros y son de su exclusiva responsabilidad.

Por otro lado, los objetos que amplían su clase con campos protegidos, instanciados por los usuarios de su código, son su responsabilidad, no la suya.

Por lo tanto, los campos / métodos protegidos no están bien documentados, o si los usuarios realmente no entienden cómo se deben usar dichos campos y métodos, tienen una buena posibilidad de causar problemas innecesarios para ellos y para usted.

Por otro lado, hacer que la mayoría de las cosas sean privadas reducirá la flexibilidad de los usuarios, e incluso puede alejarlos en busca de alternativas mantenidas, ya que es posible que no quieran crear y mantener una bifurcación solo para que las cosas sucedan a su manera.

Por lo tanto, un buen equilibrio entre privado, protegido y público es lo que realmente importa.

Ahora, decidir entre privado y protegido es el verdadero problema.

¿Cuándo usar protegido?

Cada vez que comprenda que un campo puede ser muy flexible, debe codificarse como protegido. Esa flexibilidad es: desde convertirse en nulo (donde nulo siempre se verifica y reconoce como un estado válido que no arroja excepciones), hasta tener restricciones antes de ser utilizado por su clase ex. > = 0, <100, etc., y se corrige automáticamente para valores de flujo excesivo / insuficiente, lanzando como máximo un mensaje de advertencia.

Entonces, para dicho campo protegido, podría crear un captador y solo usarlo (en lugar de usar directamente la variable de campo), mientras que otros usuarios pueden no usarlo, en caso de que quieran más flexibilidad para su código específico, en mi ejemplo podría ser como : si quieren que los valores negativos funcionen bien en su clase extendida.


-1

imo @tdammers no tiene razón y en realidad es engañoso.

Existen variables privadas para ocultar los detalles de implementación. Su clase Apodría estar usando un arraypara almacenar puntajes. Mañana es posible que desee utilizar un treeo en su priority queuelugar. Todos los usuarios de su clase necesitan una forma de ingresar puntajes y nombres addScore()y una forma de descubrir quiénes son los 10 mejores getTop(n).

No necesitan acceder a la estructura de datos subyacente. ¿Suena genial? Bueno, hay algunas advertencias.

No debe almacenar mucho estado de todos modos, la mayor parte no es necesario. El estado de almacenamiento complicará su código incluso cuando esté "segregado" a una clase específica. Piénselo, esa variable privada probablemente cambió porque otro objeto llamado método de esa clase. Todavía necesita averiguar cuándo y dónde se llamó ese método y ese método público puede llamarse en cualquier lugar teóricamente.

Lo mejor que puede hacer es limitar la cantidad de estado que contiene su programa y utilizar funciones puras cuando sea posible.


-1
  • Acceder a una variable significa acceder a su valor cuando se ejecuta el programa, hacer que una variable privada proteja su valor cuando se ejecuta el código.
  • El objetivo de la llamada "ocultación de datos" es mantener ocultos los datos internos de otras clases que usan la clase. Esas otras clases solo deberían acceder al comportamiento llamando a los métodos en la clase, no cambiando los valores de las variables directamente.
  • Al hacer que la variable sea un miembro de datos privados, puede asegurarse más fácilmente de que el valor nunca se modifique o cambie. Por otro lado, si la variable es pública, otra clase podría modificar o cambiar el valor que puede causar que otras partes del código se bloqueen.

1
Esto no parece ofrecer nada sustancial sobre los puntos formulados y explicados en 17 respuestas anteriores
mosquito

-4

Primero debe comprender el concepto de programación orientada a objetos. Tiene abstracción, encapsulación, etc.

Abstracción: se obtiene la idea de la lógica sin necesidad de conocer los detalles subrayados de la implementación.

Encapsulación: no puede ver la implementación subrayada del objeto. Solo usted puede ver la interfaz pública del objeto.

Ahora, en una implementación específica con un programa orientado a objetos como C #, Java, C ++, puede implementar estos conceptos.

privado: la implementación que debe ocultarse del mundo exterior. Para que pueda cambiar eso y el usuario de su clase no se vea afectado.

public - Esta es la interfaz por la cual uno puede usar su objeto.


1
protegido - directamente accesible por subclases (extensores) (java).
Acuario Power
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.