Modificadores de acceso en Java

Los modificadores son palabras clave que nos permiten afinar el acceso a nuestra clase y sus miembros, su alcance y comportamiento en determinadas situaciones. Por ejemplo, podemos controlar...

Introducción

Modificadores son palabras clave que nos permiten afinar el acceso a nuestra clase y sus miembros, su alcance y comportamiento en determinadas situaciones. Por ejemplo, podemos controlar qué clases/objetos pueden acceder a ciertos miembros de nuestra clase, si una clase se puede heredar o no, si podemos anular un método más tarde, si debemos anular un método más tarde, etc.

Las palabras clave modificadoras se escriben antes del tipo y el nombre de la variable/método/clase (retorno), p. private int myVar o public String toString().

Los modificadores en Java se dividen en uno de dos grupos: acceso y sin acceso:

  • Acceso: público, privado, protegido
  • Sin acceso: estático, final, abstracto, sincronizado, volátil, transitorio y nativo

Want to learn more about non-access modifiers? Check out our article Modificadores de no acceso en Java.

Modificadores de acceso {#modificadores de acceso}

Los modificadores de acceso se ocupan de la visibilidad de los miembros de la clase. Controlan si otras clases pueden ver o cambiar ciertas variables/métodos de nuestra clase.

Estos tipos de modificadores están estrechamente relacionados con una parte importante de la Programación Orientada a Objetos llamada encapsulación. Como recordatorio, la encapsulación es una idea que vincula los datos con el código que los manipula. Al controlar el acceso, puede evitar el uso indebido.

Por ejemplo, al asegurarnos de que solo se pueda acceder a ciertas variables a través de métodos bien definidos (la típica combinación de métodos get/set), nos aseguramos de que no encontraremos valores inesperados ni denegaremos el acceso externo a ciertas variables/métodos. en total.

Como se mencionó anteriormente, hay tres modificadores de acceso: público, privado y protegido. Java también proporciona control de acceso predeterminado (cuando no se especifica ningún modificador), que se comporta de manera similar a protegido.

  • público - se puede acceder al miembro desde cualquier lugar
  • protegido - el miembro solo es inaccesible desde las subclases en un paquete diferente
  • predeterminado (paquete-privado) - también conocido como acceso paquete, cualquier clase puede acceder al miembro dentro del mismo paquete
  • privado: solo otros miembros dentro de la misma clase pueden acceder al miembro

Esta tabla muestra todos los escenarios de acceso posibles para los miembros de la clase:


                                    Private   Default   Protected   Public

Misma clase Sí Sí Sí Sí Subclase (mismo paquete) No Sí Sí Sí No subclase (mismo paquete) No Sí Sí Sí Subclase (paquete diferente) No No Sí Sí No subclase (paquete diferente) No No No Sí


Esta tabla se aplica solo a los miembros de la clase, no a las clases en general. Una clase no anidada solo puede ser “pública” o sin modificador. El comportamiento es lógico, cuando una clase se declara sin un modificador, solo se puede acceder mediante código dentro del mismo paquete, y cuando se declara “pública”, también se puede usar en un paquete diferente.

Nota: una clase pública debe ser la única clase (no anidada) en el archivo, y el archivo debe tener el mismo nombre que la clase.

Por ejemplo, digamos que tenemos dos paquetes, creativamente llamados paqueteUno y paqueteDos.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
package packageOne;

public class MyPublicClass {
    String noModifierText = "No Modifier";
    private String privateText = "Private Text";
    protected String protectedText = "Protected Text";
    public String publicText = "Public Text";

    public MyPublicClass() {
        // We can access all members of a class from within that class
        System.out.println("MyPublicClass constructor:")
        System.out.println(noModifierText);
        System.out.println(privateText);
        System.out.println(protectedText);
        System.out.println(publicText);
    }
}

Tenga en cuenta que el código anterior está en un archivo llamado "MyPublicClass.java". El nombre debe coincidir con la clase, ya que la haremos pública para que podamos acceder a ella desde un paquete diferente. Lo mismo se aplica a las otras clases a continuación.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package packageOne;

class SamePackageExtends extends MyPublicClass {
    public SamePackageExtends() {
        System.out.println("SamePackageExtends constructor:")
        System.out.println(noModifierText);
        // Trying to access the private member privateText will fail, since private members
        // can only be accessed by members of the same class, even though this class extends it.
        // System.out.println(privateText);
        System.out.println(protectedText);
        System.out.println(publicText);
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
package packageOne;

class SamePackageDoesntExtend {
    // Has the same access as SamePackageExtends
    public SamePackageDoesntExtend() {
        MyPublicClass myPublicClass = new MyPublicClass();

        System.out.println("SamePackageDoesntExtend constructor:")
        System.out.println(myPublicClass.noModifierText);
        // System.out.println(myPublicClass.privateText);
        System.out.println(myPublicClass.protectedText);
        System.out.println(myPublicClass.publicText);
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
package packageTwo;

class DifferentPackageExtends extends packageOne.MyPublicClass {
    public DifferentPackageExtends() {
        System.out.println("DifferentPackageExtends constructor:")
        // System.out.println(noModifierText); // Same class or same package only
        // System.out.println(privateText);    // Same class only
        System.out.println(protectedText);
        System.out.println(publicText);
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package packageTwo;

class DifferentPackageDoesntExtend {
    public DifferentPackageDoesntExtend() {
        packageOne.MyPublicClass myPublicClass = new packageOne.MyPublicClass();

        System.out.println("DifferentPackageDoesntExtend constructor:")
        // System.out.println(myPublicClass.noModifierText);
        // System.out.println(myPublicClass.privateText);
        // System.out.println(myPublicClass.protectedText); // Same package only
        System.out.println(myPublicClass.publicText);
    }
}

Consejo: Es una práctica común encapsular una clase. Esto significa que declaramos las variables miembro como ‘privadas’ y declaramos los métodos ‘públicos’ que las manipulan. Por ejemplo, queremos permitir que alguien cambie el campo int ID pero también queremos asegurarnos de que int ID sea estrictamente un número entero positivo. A través del método público, primero podemos ejecutar una verificación y manipular el campo si el valor dado pasa nuestra verificación. Esta es una construcción llamada método set(), y generalmente está acompañada por un método get() (ya que no podemos leer miembros privados fuera de nuestra clase) o cuando queremos controlar cómo y cuándo se puede leer el valor de una variable.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
class GetSetExample {
    ...
    private int ID = 0; // Default value
    public setID(int n) {
        if (n > 0) {
            ID = n;
        }
        else ID = 0;
    }
    public int getID() {
        // Potential read conditions that need to be met

        return ID;
    }
    ...
}

Otra cosa a tener en cuenta es que “protegido” es el menos utilizado de todos los modificadores de acceso. Se puede omitir fácilmente si queremos. Incluso en un paquete diferente podemos simplemente heredar la clase a cuyos miembros protegidos queremos acceder, y luego acceder a ellos a través de esa clase heredada.

Con eso en mente, protegido se usa con mayor frecuencia como una pauta que dice "Este miembro no está destinado a ser accedido por personas que no sean subclases en un paquete diferente", por lo que, aunque podemos omitir fácilmente el control de acceso protegido , no es aconsejable, ya que lo más probable es que se haya puesto allí por alguna razón.

Conclusión

Los modificadores son palabras clave que nos permiten afinar el acceso a nuestra clase y sus miembros, su alcance y comportamiento en determinadas situaciones. Proporcionan rasgos fundamentales para nuestras clases y sus miembros. Cada desarrollador debe estar completamente familiarizado con ellos para hacer el mejor uso de ellos.

Licensed under CC BY-NC-SA 4.0