¿Por qué los atributos en Java pueden ser públicos?


Como todo el mundo sabe, Java sigue los paradigmas de la orientación de objetos, donde la encapsulación de datos dice, que los campos (atributos) de un objeto deben ocultarse para el mundo exterior y solo se accede a través de métodos o que los métodos son la interfaz solo de la clase para el mundo exterior. Entonces, ¿por qué es posible declarar un campo en Java como público, lo que estaría en contra del paradigma de encapsulación de datos?

Author: strauberry, 2011-12-09

12 answers

Creo que es posible porque cada regla tiene su excepción, cada mejor práctica puede ser anulada en ciertos casos.

Por ejemplo, a menudo expongo miembros de datos finales estáticos públicos como públicos (por ejemplo, constantes). No creo que sea dañino.

Señalaré que esta situación es cierta en otros lenguajes además de Java: C++, C#, etc.

Los idiomas no siempre necesitan protegernos de nosotros mismos.

En el ejemplo de Oli, ¿cuál es el daño si lo escribo esto ¿camino?

public class Point {
   public final int x;
   public final int y;

   public Point(int p, int q) {
      this.x = p;
      this.y = q;
   } 
}

Es inmutable y seguro. Los miembros de datos pueden ser públicos, pero no puedes hacerles daño.

Además, es un pequeño secreto sucio que "privado" no es realmente privado en Java. Siempre puedes usar la reflexión para evitarlo.

Así que relájate. No es tan malo.

 74
Author: duffymo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-09 12:48:20

Para la flexibilidad. Sería un gran dolor si no fuera capaz de escribir:

class Point {
    public int x;
    public int y;
}

Hay muy poca ventaja para ocultar esto detrás de los getters y setters.

 52
Author: Oliver Charlesworth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-09 12:48:00

Porque la "encapsulación de datos" rígida no es el único paradigma, ni una característica obligatoria de la orientación de objetos.

Y, más al punto, si uno tiene un atributo de datos que tiene un método public setter y un método public getter, y los métodos no hacen otra cosa que realmente establecer/obtener el atributo, ¿cuál es el punto de mantenerlo privado?

 12
Author: Hot Licks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-09 12:49:39

No todas las clases siguen el paradigma de encapsulación (por ejemplo, las clases de fábrica). Para mí, esto aumenta la flexibilidad. Y de todos modos, es responsabilidad del programador, no del lenguaje, el alcance apropiado.

 5
Author: mre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-09 12:50:04

Discutiendo el lado bueno de las variables públicas... Like... :)

Puede haber muchas razones para usar variables public. Vamos a comprobarlos uno por uno:

Rendimiento

Aunque rara, habrá algunas situaciones en las que importa. La sobrecarga de la llamada al método tendrá que evitarse en algunos casos.

Constantes

Podemos usar variables públicas para constantes, que no se pueden cambiar después de inicializarse en constructor. También ayuda al rendimiento. A veces estas pueden ser constantes estáticas, como la cadena de conexión a la base de datos. Por ejemplo,

public static final String ACCEPTABLE_PUBLIC = "Acceptable public variable";

Otros casos

Hay algunos casos en los que public no hace ninguna diferencia o tener un getter y un setter es innecesario. Un buen ejemplo con Point ya está escrito como respuesta.

 2
Author: Jomoos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-09 13:48:21

El diseño orientado a objetos no requiere encapsulación. Esa es una buena práctica en lenguajes como Java que tiene mucho más que ver con el diseño del lenguaje que OO.

Es solo una buena práctica encapsular siempre en Java por una simple razón. Si no encapsula, no puede encapsular más tarde sin cambiar la firma de un objeto. Por ejemplo, si su empleado tiene un nombre, y lo hace público, es employee.name. Si luego quieres encapsularlo, terminas con empleado.getName () y empleado.setName (). esto, por supuesto, romperá cualquier código usando su clase de empleado. Por lo tanto, en Java es una buena práctica encapsular todo, para que nunca tenga que cambiar la firma de un objeto.

Algunos otros lenguajes OO (ActionScript3, C#, etc.) admiten propiedades verdaderas, donde agregar un getter/setter no afecta a la firma. En este caso, si tiene un getter o setter, reemplaza la propiedad pública con la misma firma, por lo que puede fácilmente cambiar de ida y vuelta sin romper el código. En estos lenguajes, la práctica de siempre encapsular ya no es necesaria.

 1
Author: Dan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-09 14:07:36

Java es una rama de los lenguajes de sintaxis de estilo C. Esos lenguajes soportaban struct s que eran alias de desplazamiento fijos para un bloque de memoria que generalmente se determinaba que era considerado "un elemento". En otras palabras, las estructuras de datos se implementaron con structs.

Mientras que el uso de una estructura viola directamente los objetivos de encapsulación de la Programación Orientada a Objetos, cuando Java fue lanzado por primera vez la mayoría de la gente era mucho más competente en la programación iterativa (procedimental). Al exponer miembros como public puede usar efectivamente una clase Java de la misma manera que podría usar una C struct a pesar de que las implementaciones subyacentes de los dos envrionments eran drásticamente diferentes.

Hay algunos escenarios donde incluso se puede hacer esto con una encapsulación adecuada. Por ejemplo, muchas estructuras de datos consisten en nodos de dos o más punteros, uno para apuntar a los datos "contenidos", y uno o más para apuntar a las "otras" conexiones al resto de la estructura de datos. En tal caso, usted puede crear una clase privada que no tenga visibilidad fuera de la clase "estructura de datos" (como una clase interna) y dado que todo el código para recorrer la estructura está contenido dentro del mismo archivo .java, puede eliminar los métodos .getNext() de la clase interna como una optimización de rendimiento.

 1
Author: Edwin Buck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-09 17:19:17

Creo que la encapsulación de datos se ofrece más como una característica adicional y no como un requisito o regla obligatoria, por lo que el codificador tiene la libertad de usar su sabiduría para aplicar las características y ajustarlas según sus necesidades.Por lo tanto, es flexible!

Un ejemplo relacionado puede ser uno dado por @ Oli Charlesworth

 0
Author: samridhi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-13 08:19:56

Soy solo un principiante, pero si la declaración pública no existe, el desarrollo de Java será realmente complicado de entender. Porque usamos declaraciones públicas, privadas y otras para simplificar la comprensión del código, como jars que usamos y que otros han creado. Lo que quiero decir es que no necesitamos inventar, necesitamos aprender y seguir adelante.

Espero disculparme por mi inglés, estoy tratando de mejorar y espero escribir claramente en el futuro.

 0
Author: ZaoTaoBao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-14 08:24:33

Los modificadores de accesibilidad son una implementación del concepto de encapsulación en lenguajes OO (veo esta implementación como una forma de relajar este concepto y permitir cierta flexibilidad). Hay lenguajes OO puros que no tienen modificadores de accesibilidad, como Smalltalk. En este lenguaje todo el estado (variables de instancia) es privado y todos los métodos son públicos, la única forma de modificar o consultar el estado de un objeto es a través de sus métodos de instancia. La ausencia de accesibilidad los modificadores para los métodos obligan a los desarrolladores a adoptar ciertas convenciones, por ejemplo, los métodos en un protocolo privado (los protocolos son una forma de organizar los métodos en una clase) no deben usarse fuera de la clase, pero ninguna construcción del lenguaje hará cumplir esto, si lo desea puede llamar a esos métodos.

 0
Author: Diego,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-14 14:23:28

Usar public o no realmente depende de si hay un invariante a mantener. Por ejemplo, un objeto de datos puros no restringe la transición de estado de ninguna manera, por lo que no tiene sentido encapsular los miembros con un montón de accesores que no ofrecen más funcionalidad que exponer el miembro de datos como público.

Si tiene tanto un getter como un setter para un miembro de datos no privado en particular que no proporciona más funcionalidad que getting y setting, entonces es posible que desee reevalúa tu diseño o haz que el miembro sea público.

 0
Author: Hazok,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-15 06:27:25

Realmente no puedo pensar en una buena razón para no usar getters y setters fuera de la pereza. Effective Java, que es ampliamente considerado como uno de los mejores libros de java, dice que siempre use getters y setters. Si no necesita saber por qué siempre debe usar getters y setters, omita este párrafo. No estoy de acuerdo con el ejemplo de la respuesta número 1 de un Punto como un tiempo para no usar getters y setters. Hay varios problemas con esto. ¿Qué pasa si necesita cambiar el tipo de numero. Por ejemplo, una vez, cuando estaba experimentando con gráficos, descubrí que con frecuencia cambiaba de opinión en cuanto al clima, quiero almacenar la ubicación en forma de java o directamente como int, como demostró. Si no usara getters y setters y cambiara esto tendría que cambiar todo el código que usó la ubicación. Sin embargo, si no lo hacía podría cambiar el getter y setter.

Los getters y setters son un dolor en Java. En Scala puede crear miembros de datos públicos y luego getters y / o setters más tarde sin cambiar la API. ¡Esto te da lo mejor de ambos mundos! Tal vez, Java arreglará esto algún día.

 0
Author: jgleoj23,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-24 04:01:07