Tutorial de Java

Control de Acceso

Anterior | Siguiente
En C++ el control de acceso es menos complicado que en Java. Cualquier miembro individual de una clase en C++, puede ser designado como: private, public o protected.

Un miembro private solamente puede ser accedido por otros miembros de la propia clase; no puede ser accedido por miembros de una clase heredada. Es la designación más restrictiva de todas.

Un miembro designado como public puede ser accedido desde cualquier código dentro del ámbito de un objeto instanciado a partir de la clase. Es la designación menos restrictiva.

La designación de protected entra en juego solamente cuando se ve involucrada la herencia. Un miembro designado como protected aparece como public para los miembros de clases derivadas de la clase y aparece como private para todas las demás.

En C++ hay un segundo nivel de control de acceso con las mismas palabras reservadas, que no tiene analogía en Java, y que se aplica a nivel de la herencia de una clase desde otra clase.

También en C++, hay un aspecto adicional que son las funciones friend de una clase. Estas funciones tienen acceso a todos los miembros privados y protegidos de esa clase. Esta función puede ser una función miembro de otra clase o simplemente una función aislada (que no está soportada en Java). Java no tiene nada semejante a las funciones friend de C++.

El control de acceso se aplica siempre a nivel de clase, no a nivel de objeto. Es decir, los métodos de instancia de un objeto de una clase determinada tienen acceso directo a los miembros privados de cualquier otro objeto de la misma clase.

En Java, el control de acceso se complica un poco por la inclusión de la noción de package (paquete). Java implementa los mismos tres especificadores de acceso que C++ (aunque no necesariamente con el mismo significado) y, además, implementa ese cuarto especificador si no se ha indicado ninguno de los otros tres, que es el definido como package, default o friendly.

Por lo tanto, cuando se crea una nueva clase en Java, se puede especificar el nivel de acceso que se quiere para las variables de instancia y los métodos definidos en la clase: private, protected, public y package.

La tabla siguiente muestra el nivel de acceso que está permitido a cada uno de los especificadores:

Nivel de Acceso

clase

subclase

paquete

todos

Private

X

     
Protected

X

X*

X

 
Public

X

X

X

X

Package

X

 

X

 

Si se profundiza en el significado de la tabla, se puede observar que la columna clase indica que todos los métodos de una clase tienen acceso a todos los otros miembros de la misma clase, independientemente del nivel de acceso especificado.

La columna subclase se aplica a todas las clases heredadas de la clase, independientemente del paquete en que residan. Los miembros de una subclase tienen acceso a todos los miembros de la superclase que se hayan designado como public. El asterisco (*) en la intersección subclase-protected quiere decir que si una clase es a la vez subclase y está en el mismo paquete que la clase con un miembro protected, entonces la clase tiene acceso a es miembro protegido.

En general, si la subclase no se encuentra en el mismo paquete que la superclase, no tiene acceso a los miembros protegidos de la superclase. Los miembros de una subclase no tienen acceso a los miembros de la superclase catalogados como private o package, excepto a los miembros de una subclase del mismo paquete, que tienen acceso a los miembros de la superclase designados como package.

La columna paquete indica que las clases del mismo paquete tienen acceso a los miembros de una clase, independientemente de su árbol de herencia. La tabla indica que todos los miembros protected, public y package de una clase pueden ser accedidos por otra clase que se encuentre en el mismo paquete. Esto puede asemejarse un poco a la designación de funciones friend en C++, salvando las diferencias, que no son pocas.

En C++, se puede calificar un método en una clase diferente como friend de una clase determinada y ese status de friend no se extiende a ningún otro método de la clase, es decir, una persona de otra familia puede ser tu amigo, pero no por eso tienen que ser tus amigos el resto de los miembros de la familia de tu amigo.

En Java, colocando dos o más clases en el mismo paquete se hace que la relación friend, de amistad, se extienda a todos los métodos de las clases, es decir, si eres amigo de uno de los miembros de una familia, serás amigo automáticamente de todos y cada uno de los componentes de esa familia.

La columna todos indica que los privilegios de acceso para métodos que no están en la misma clase, ni en una subclase, ni en el mismo paquete, se encuentran restringidos a los miembros públicos de la clase.

Si se observa la misma tabla desde el punto de vista de las filas, podemos describir los calificadores de los métodos.

private

    private String NumeroDelCarnetDeIdentidad;

Las variables y métodos de instancia privados sólo pueden ser accedidos desde dentro de la clase. No son accesibles desde las subclases de esa clase. Hay que resaltar una vez más, que un método de instancia de un objeto de una clase puede acceder a todos los miembros privados de ese objeto, o miembros privados de cualquier otro objeto de la misma clase. Es decir, que en Java el control de acceso existe a nivel de clase, pero no a nivel de objeto de la clase.

public

    public void CualquieraPuedeAcceder(){}

Cualquier clase desde cualquier lugar puede acceder a las variables y métodos de instancia públicos.

protected

    protected void SoloSubClases(){}

Sólo las subclases de la clase y nadie más puede acceder a las variables y métodos de instancia protegidos. Los métodos protegidos pueden ser vistos por las clases derivadas, como en C++, y también, en Java, por los paquetes. Todas las clases de un paquete pueden ver los métodos protegidos de ese paquete. Esto difiere significativamente de C++, en donde los miembros protegidos solamente pueden ser accedidos por miembros de la misma clase o miembros de subclases.

package (fiendly, sin declaración específica)

    void MetodoDeMiPaquete(){}

Por defecto, si no se especifica el control de acceso, las variables y métodos de instancia se declaran package (friendly, amigas), lo que significa que son accesibles por todos los objetos dentro del mismo paquete, pero no por los externos al paquete. Aparentemente, parece lo mismo que protected; la diferencia estriba en que la designación de protected es heredada por las subclases de un paquete diferente, mientras que la designación package no es heredada por subclases de paquetes diferentes.

Debido a la complejidad y posible confusión respecto a los niveles de protección que proporciona Java para permitir el control preciso de la visibilidad de variables y métodos, se puede generar otra tabla en base a cuatro categorías de visibilidad entre los elementos de clase:

 

private

sin modificador

protected

public

Misma clase

SI

SI

SI

SI

Misma subclase de paquete

NO

SI

SI

SI

Misma no-subclase de paquete

NO

SI

SI

SI

Subclase de diferente paquete

NO

NO

SI

SI

No-subclase de diferente paquete

NO

NO

NO

SI

Y una guía de uso indicaría tener en cuenta lo siguiente:

  • Usar private para métodos y variables que solamente se utilicen dentro de la clase y que deberían estar ocultas para todo el resto
  • Usar public para métodos, constantes y otras variables importantes que deban ser visibles para todo el mundo
  • Usar protected si se quiere que las clases del mismo paquete puedan tener acceso a estas variables o métodos
  • Usar la sentencia package para poder agrupar las clases en paquetes
  • No usar nada, dejar la visibilidad por defecto (default, package) para métodos y variables que deban estar ocultas fuera del paquete, pero que deban estar disponibles al acceso desde dentro del mismo paquete. Utilizar protected en su lugar si se quiere que esos componentes sean visibles fuera del paquete

Navegador

Home | Anterior | Siguiente | Indice | Correo