176.Visibilidad [scope]

Ámbitoo zona del código en el que un elemento de Java puede referenciarse por su nombre.

Java define 4 modificadores fundamentales que califican a Clases, Métodos y Campos:

private

el elemento sólo es accesible dentro del fichero en el que se define

de paquete

el elemento sólo es accesible dentro del paquete en el que se define
(clases en el mismo directorio).

protected

el elemento es accesible dentro del paquete en el que se define
y, además, en las
Subclases.

public

                el elemento es accesible desde cualquier sitio.

Las reglas básicas se pueden resumir en la siguiente tabla

 

visibilidad

modificador

fichero

paquete

(directorio)

subclases (extends)

cuaquiera

private

NO

NO

NO

de paquete

(package local)

NO

NO

protected

NO

public

 

Las clases pueden ser “public” (para todo el mundo), “de paquete” (restringidas a un paquete) o “private” (restringidas a un fichero).

 

Se recomienda que los Campo sean siempre “private” (restringidos a un fichero).

 

Los métodos suelen aprovechar frecuentemente las facilidades java de control de visibilidad.

El siguiente ejemplo recoge toda la casuística y muestra qué es posible y que no:

 

a/A.java

package a;

 

public class A {

 

  private void metodoPrivate() {

  }

 

  /* de paquete */ void metodoFriendly() {

  }

 

  protected void metodoProtected() {

  }

 

  public void metodoPublic() {

  }

 

  void acceso(A a) {

    a.metodoPrivate();

    a.metodoFriendly();

    a.metodoProtected();

    a.metodoPublic();

  }

}

a/A2.java

package a;

 

public class A2 {

 

  void acceso(A a) {

    a.metodoPrivate();    // mal

    a.metodoFriendly();

    a.metodoProtected();

    a.metodoPublic();

  }

}

b/B.java

package b;

 

import a.A;

 

public class B {

 

  void acceso(A a) {

    a.metodoPrivate();    // mal

    a.metodoFriendly();   // mal

    a.metodoProtected();  // mal

    a.metodoPublic();

  }

}

c/C.java

package c;

 

import a.A;

 

public class C extends A {

 

  void acceso(A a) {

    a.metodoPrivate();    // mal

    a.metodoFriendly();   // mal

    a.metodoProtected();  // mal

    a.metodoPublic();

  }

 

  void acceso(C c) {

    c.metodoPrivate();    // mal

    c.metodoFriendly();   // mal

    c.metodoProtected();

    c.metodoPublic();

  }

}   

 

Nótese la diferencia en la clase C que extiende a la clase A, que puede acceder a los métodos protegidos de A siempre y cuando lo haga como método heredado, que no como método de A.

Cuando se intenta compilar, el compilador detecta y reporta los siguientes errores semánticos:

$ javac a/*.java b/*.java c/*.java

a/A2.java:6: metodoPrivate() has private access in a.A

    a.metodoPrivate();    // mal

     ^

b/B.java:8: metodoPrivate() has private access in a.A

    a.metodoPrivate();    // mal

     ^

b/B.java:9: metodoFriendly() is not public in a.A;

                             cannot be accessed from outside package

    a.metodoFriendly();   // mal

     ^

b/B.java:10: metodoProtected() has protected access in a.A

    a.metodoProtected();  // mal

     ^

c/C.java:8: metodoPrivate() has private access in a.A

    a.metodoPrivate();    // mal

     ^

c/C.java:9: metodoFriendly() is not public in a.A;

                             cannot be accessed from outside package

    a.metodoFriendly();   // mal

     ^

c/C.java:10: metodoProtected() has protected access in a.A

    a.metodoProtected();  // mal

     ^

c/C.java:15: metodoPrivate() has private access in a.A

    c.metodoPrivate();    // mal

     ^

c/C.java:16: metodoFriendly() is not public in a.A;

                             cannot be accessed from outside package

    c.metodoFriendly();   // mal

     ^

9 errors

Temas relacionados

Vademécum