Alcance de las variables
Cada variable solo está disponible (y accesible) en el contexto en el que se ha declarado. Para determinar el contexto, consulte las marcas de apertura y cierre más cercanas que rodean la declaración. La mayoría de los lenguajes de programación usan llaves ({}
) para marcar el principio y el final de un bloque de código. Echa un vistazo a este ejemplo:
No hay necesidad de entender cada bit de código aquí; solo enfóquese en las llaves. 🙂 Cuando hablamos de la disponibilidad de una variable dentro de un contexto, nos referimos al alcance. Aquí, puede ver que la variable root
se ha declarado entre las dos llaves con un círculo en púrpura. El alcance de esa variable es todo entre esos dos llaves.
El alcance de una variable puede ser tanto local como global, dependiendo de dónde se declare una variable. Una variable global puede estar disponible para todas las clases y métodos dentro de un programa, mientras que una variable local solo puede estar disponible dentro del método que se declara en:
Aquí, hemos ampliado un poco el código y ampliado nuestro primer bloque de código para incluir otro. Si traza las líneas moradas, puede ver que los corchetes del primer bloque abarcan todo el código del segundo. A continuación, puede ver que se ha declarado una nueva variable, spy
, dentro del ámbito local verde.
Dado que la variable root
ha sido declarada en el ámbito global, eso significa que es accesible para todo lo que esté dentro de los corchetes morados, incluido todo lo declarado en el ámbito local. En el segundo bloque de código, puede ver una línea justo debajo de la declaración de variable espía que usa root
. ¡Está permitido!
Sin embargo, lo que está en el ámbito local no está disponible para el ámbito global ni para ningún otro bloque de código local. Echemos un vistazo a otro ejemplo:
Aquí hemos agregado otro bloque de código, que tiene su propio ámbito local y su propia variable, anotherSpy
. Ahora, echa un vistazo a la última línea de nuestro bloque de variables espía:
System.out.println(anotherSpy); // Error
¡Parece que hay un error! Esto se debe a que está tratando de usar la variable anotherSpy
. Pero no puede porque anotherSpy
no está dentro del ámbito global ni en el mismo ámbito local. Eso significa que este bloque de código no puede acceder a él. anotherSpy
solo está disponible en el bloque de código en el que se ha declarado.
lo mismo es cierto en la otra dirección. Puedes ver que la última línea de nuestro último bloque de código también tiene un error:
System.out.println(spy); // Error
Aquí, está tratando de usar la variable spy de otro bloque de código. Pero no puede, ya que spy
no está en el mismo ámbito que el bloque de código que intenta usarlo.
Ámbito de variable en clases
Cuando se declara una clase, se aplican las mismas reglas generales de ámbito: cada variable solo es accesible dentro de su bloque de declaración. Experimentemos con una clase unicornio:
Al igual que en nuestro primer ejemplo, hay variables de clase globales y locales. Repasemos en detalle:
-
Las variables
height
ypower
son campos de la clase y son accesibles en cualquier lugar dentro de la clase. -
La variable
minutesToSleep
solo es accesible dentro del ámbito local del bloque de código en el que se declara. -
La variable
minutesToRun
solo es accesible dentro del ámbito local del bloque de código en el que se declara.
El alcance de una variable limita su accesibilidad por definición. Sin embargo, los campos de clase son accesibles fuera de la clase y pueden ser utilizados por cualquier otro bloque de código.
En nuestro ejemplo, aquellos que son height
y power
. Si declaramos una variable Unicorn, podemos leer o alterar esos valores:
Ser capaz de jugar con variables de clase puede tener graves consecuencias. La buena noticia es que puedes controlar eso. Antes de comprobar cómo, asegúrese de practicar con el alcance variable.
¡Pruébalo tú mismo!
Control de acceso
Vamos a utilizar la idea del control de acceso implementando el acceso restringido a una clase, módulo o archivo. ¡Ya sabes lo que son una clase y un archivo ya que hemos estado trabajando con ellos!
Un módulo es un paquete de archivos fuente relacionados asociados con un nombre, como un framework. Un framework es un conjunto de funcionalidades agrupadas por un contexto particular. Acelera el proceso de desarrollo y proporciona orientación sobre cómo escribir el código.
Hay una serie de frameworks proporcionados por cada entorno de desarrollo. El hecho es que la implementación de esos marcos está mucho más allá de lo que los desarrolladores que los usan pueden ver y utilizar. Esto se hace restringiendo el acceso a los detalles de la implementación, también conocido como implementación de control de acceso.
Niveles de control
En Java, debe usar una de las palabras clave para designar un nivel de control:
-
Público: visible para el mundo y, por lo tanto, el menos restrictivo
-
Protegido: visible para el paquete y todas sus subclases
- normalmente visibles solo para el paquete en el que se encuentran (configuración predeterminada)
-
Privado: solo accesible en el contexto en el que se definen (dentro de la clase en la que se encuentra)
Poner en marcha esas distintas restricciones hace que el desarrollo sea mucho más fácil. No tiene que preocuparse por la visibilidad no deseada de su implementación y, más aún, por las modificaciones no deseadas.
Coloque una palabra clave adecuada delante de la declaración relacionada:
Entonces, si intenta acceder a miembros privados desde fuera de la clase, obtendrá errores:
Los niveles de control se pueden asignar a elementos de clase, así como a clases:
public class PublicClass {}private class PrivateClass {}
Además de la seguridad, especificar niveles de control para miembros de clase proporciona una mejor legibilidad. Cuando un desarrollador está preparando un archivo de origen, siempre está claro qué elementos se pueden usar externamente.
Jerarquía de control
Un elemento puede tener el mismo o más restrictivo nivel de control que el elemento que lo contiene:
En el ejemplo anterior, la clase se declara como public
. Dado que la clase es el elemento contenedor, esto significa que todos los elementos de esa clase pueden tener el mismo o menor nivel de exposición. En este caso, incluye todos los niveles.
Si declaras una clase como private
, sus elementos solo pueden ser package-private
o private
:
class PrivateClass { int internalProperty = 0; // automatically assigned package-private by default protected defaultProperty = true; // automatically assigned package-private public boolean publicProperty = true; // automatically converted to package-private private String fileprivateProperty = "Hello!"; //only available to the class private static void privateMethod() { }}
En el ejemplo anterior, hemos añadido una atributo sin una palabra clave de control de acceso explícita. En este escenario, de forma predeterminada, asume el nivel del elemento que lo contiene. En este caso, es nuestra clase, por lo que asume el nivel de PrivateClass
.
Una clase de nivel superior no se puede marcar como privada, pero configurarla como predeterminada la colocará en el nivel protegido por paquetes. Al declarar una variable de una clase, si el nivel de control del contexto de declaración es mayor que el de la clase, la variable también debe tener un nivel de control explícito. Declaremos una variable FileprivateClass:
String a = PrivateClass(); // Errorprivate String b = PrivateClass(); // Okprivate String c = PrivateClass(); // Ok
Como puede ver, si el nivel de acceso predeterminado del contexto de la variable es mayor que una clase que le está asignando, debe especificar explícitamente el nivel de la variable como el mismo o menor que el de la clase.
Resumen
En este capítulo, ha aprendido sobre la accesibilidad de variables:
-
Un ámbito de una variable es el área de código donde se ha declarado.
-
El ámbito de variable general se aplica a todos los bloques de código, incluidas las clases.
-
Otra forma necesaria de controlar el acceso a variables y funciones es usar niveles de control: público, protegido, protegido por paquetes y privado.