Sunteți pe pagina 1din 11

Universidad Los Ángeles de Chimbote Curso: Técnicas de Programación

CONTROL DE ACCESO
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

Docente: Ing. Pedro Beltrán Canessa ~1~


Universidad Los Ángeles de Chimbote Curso: Técnicas de Programación

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.

Docente: Ing. Pedro Beltrán Canessa ~2~


Universidad Los Ángeles de Chimbote Curso: Técnicas de Programación

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:

Docente: Ing. Pedro Beltrán Canessa ~3~


Universidad Los Ángeles de Chimbote Curso: Técnicas de Programación

Private Sin Protected Public


modificador
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 NO NO NO SI
paquete

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

Docente: Ing. Pedro Beltrán Canessa ~4~


Universidad Los Ángeles de Chimbote Curso: Técnicas de Programación

ENCAPSULAMIENTO

Como se puede observar de los diagramas, las variables del objeto se localizan en el centro o
núcleo del objeto. Los métodos rodean y esconden el núcleo del objeto de otros objetos en el
programa. Al empaquetamiento de las variables de un objeto con la protección de sus métodos
se le llama encapsulamiento. Típicamente, el encapsulamiento es utilizado para esconder
detalles de la puesta en práctica no importantes de otros objetos. Entonces, los detalles de la
puesta en práctica pueden cambiar en cualquier tiempo sin afectar otras partes del programa.
El encapsulamiento de variables y métodos en un componente de software ordenado es,
todavía, una simple idea poderosa que provee dos principales beneficios a los desarrolladores
de software:
Modularidad, esto es, el código fuente de un objeto puede ser escrito, así como darle
mantenimiento, independientemente del código fuente de otros objetos. Así mismo, un
objeto puede ser transferido alrededor del sistema sin alterar su estado y conducta.
Ocultamiento de la información, es decir, un objeto tiene una "interfaz publica" que
otros objetos pueden utilizar para comunicarse con él. Pero el objeto puede mantener
información y métodos privados que pueden ser cambiados en cualquier tiempo sin
afectar a los otros objetos que dependan de ello.
Los objetos proveen el beneficio de la modularidad y el ocultamiento de la información. Las
clases proveen el beneficio de la reutilización. Los programadores de software utilizan la misma
clase, y por lo tanto el mismo código, una y otra vez para crear muchos objetos.
En las implantaciones orientadas a objetos se percibe un objeto como un paquete de datos y
procedimientos que se pueden llevar a cabo con estos datos. Esto encapsula los datos y los
procedimientos. La realidad es diferente: los atributos se relacionan al objeto o instancia y los
métodos a la clase. ¿Por qué se hace así? Los atributos son variables comunes en cada objeto
de una clase y cada uno de ellos puede tener un valor asociado, para cada variable, diferente al
que tienen para esa misma variable los demás objetos. Los métodos, por su parte, pertenecen
a la clase y no se almacenan en cada objeto, puesto que sería un desperdicio almacenar el
mismo procedimiento varias veces y ell o va contra el princi pi o de reutilización de código.

Docente: Ing. Pedro Beltrán Canessa ~5~


Universidad Los Ángeles de Chimbote Curso: Técnicas de Programación

Imaginemos que se crea una clase, una docena de programadores tienen acceso a dicha clase
y la utilizan a discreción, posteriormente dicha clase comienza a comportarse de una manera
inesperada debido a que los valores que algunas variables han tomado no fueron anticipados y
todo comienza a desmoronarse. Para corregir el problema se crea una versión más nueva de
dicha clase y listo.

Bueno, a esto le llamamos flexibilidad y capacidad de mantenimiento, ambas son características


y beneficios de la programación Orientada a Objetos (OO) pero para que una clase pueda
cumplir dichas funciones los programadores debemos de hacer algo. Imaginemos que creamos
una clase con variables de instancia públicas a las cuales podemos acceder sin problemas desde
fuera de la misma clase...

public class MiClase{


public int tipo;
}
class AccesoDirecto{
public static void main(String[] args){
MiClase mc = new MiClase();
mc.tipo = -5; //1
}
}
Analizando el código anterior podemos darnos cuenta de que las variables enteras tipo y clase
son públicas y pueden ser accedidas directamente a través de una instancia de la clase MiClase,
esto compila sin ningún problema, digamos que es 'legal', sin embargo, ¿qué pasa si
ingresamos un valor que no se supone debe de tener una variable (en este caso el -5 que le
asignamos a tipo)?, simplemente no hay nada que nos detenga para hacerlo. La única manera
de proteger el código es escribiendo un método que nos permita regular los valores que cada
variable puede tener y escondiendo las variables para que no se pueda acceder a ellas de
manera directa, esto es el principio básico de encapsulamiento.

Si se desea flexibilidad, buen mantenimiento y extensibilidad, nuestro diseño en el código debe


de incluir encapsulamiento, para ello debemos de hacer lo siguiente:

Mantener las variables de instancia protegidas (puede ser con un modificador de acceso,
p.ej., private)

Docente: Ing. Pedro Beltrán Canessa ~6~


Universidad Los Ángeles de Chimbote Curso: Técnicas de Programación

Hacer métodos de acceso públicos para forzar al acceso a las variables por medio de dichos
métodos en lugar de acceder directamente.

Utilizar las convenciones de código para los nombres de los métodos, p. ej., set y get.

El ejemplo anterior modificado para un buen encapsulamiento quedaría así:

public class MiClase{


private int tipo;
public void setTipo(int t){
tipo = t;
}

public int getTipo(){


return tipo;
}
}

class AccesoIndirecto{
public static void main(String[] args){
MiClase mc = new MiClase();
mc.setTipo(5);
System.out.println("El tipo es:" + mc.getTipo());
}

}
Si nos fijamos un poquito, en el método setTipo() no existen validaciones para prevenir que un
valor no válido sea asignado a la variable, sin embargo, el proveer de un método de este tipo
desde el diseño inicial de la aplicación nos permite posteriormente modificar el comportamiento
de la misma sin afectar los métodos utilizados, tal vez en un futuro se desee que dicha variable
solamente pueda tener uno entre un rango de valores y se podrán aplicar posteriormente los
cambios sin que haya repercusiones negativas.

Docente: Ing. Pedro Beltrán Canessa ~7~


Universidad Los Ángeles de Chimbote Curso: Técnicas de Programación

THIS
Al acceder a variables de instancia de una clase, la palabra clave this hace referencia a los
miembros de la propia clase en el objeto actual; es decir, this se refiere al objeto actual sobre el
que está actuando un método determinado y se utiliza siempre que se quiera hace referencia al
objetoactual de la clase. Volviendo al ejemplo de MiClase, se puede añadir otro constructor de
la forma siguiente:
public class MiClase {
int i;
public MiClase() {
i = 10;
}
// Este constructor establece el valor de i
public MiClase( int valor ) {
this.i = valor; // i = valor
}
// Este constructor también establece el valor de i
public MiClase( int i ) {
this.i = i;
}
public void Suma_a_i( int j ) {
i = i + j;
}
}
Aquí this.i se refiere al entero i en la clase MiClase, que corresponde al objeto actual. La
utilización de this en el tercer constructor de la clase, permite referirse directamente al objeto
en sí, en lugar de permitir que el ámbito actual defina la resolución de variables, al utilizar i
como parámetro formal y después this para acceder a la variable de instancia del objeto actual.
La utilización de this en dicho contexto puede ser confusa en ocasiones, y algunos
programadores procuran no utilizar variables locales y nombres de parámetros formales que
ocultan variables de instancia. Una filosofía diferente dice que en los métodos de inicialización y
constructores, es bueno seguir el criterio de utilizar los mismos nombres por claridad, y utilizar
this para no ocultar las variables de instancia. Lo cierto es que es más una cuestión de gusto
personal que otra cosa el hacerlo de una forma u otra.
La siguiente aplicación de ejemplo, utiliza la referencia this al objeto para acceder a una
variable de instancia oculta para el método que es llamado.

Docente: Ing. Pedro Beltrán Canessa ~8~


Universidad Los Ángeles de Chimbote Curso: Técnicas de Programación

class javathis {
// Variable de instancia
int miVariable;

// Constructor de la clase
public javathis() {
miVariable = 5;
}

// Metodo con argumentos


void miMetodo(int miVariable) {
System.out.println( "La variable Local miVariable contiene " + miVariable );
System.out.println( "La variable de Instancia miVariable contiene " + this.miVariable );
}

public static void main( String args[] ) {


// Instanciamos un objeto del tipo de la clase
javathis obj = new javathis();
// que utilizamos para llamar a su unico metodo
obj.miMetodo( 10 );
}
}

SUPER
Si se necesita llamar al método padre dentro de una clase que ha reemplazado ese método, se
puede hacer referencia al método padre con la palabra clave super:
import MiClase;
public class MiNuevaClase extends MiClase {
public void Suma_a_i( int j ) {
i = i + ( j/2 );
super.Suma_a_i( j );
}
}

Docente: Ing. Pedro Beltrán Canessa ~9~


Universidad Los Ángeles de Chimbote Curso: Técnicas de Programación

En el siguiente código, el constructor establecerá el valor de i a 10, después lo cambiará a 15 y


finalmente el método Suma_a_i() de la clase padre MiClase lo dejará en 25:
MiNuevaClase mnc;
mnc = new MiNuevaClase();
mnc.Suma_a_i( 10 );
Super es un concepto que no existe en C++, al menos no con una implementación similar a
Java. Si un método sobreescribe un método de su superclase, se puede utilizar la palabra clave
super para eludir la versión sobreescrita de la clase e invocar a la versión original del método
en la supreclase. Del mismo modo, se puede utilizar super para acceder a variables miembro de
la superclase.
En el ejemplo, la aplicación utiliza super para referirse a una variable local en un método y a
una variable de la superclase que tiene el mismo nombre. El programa también utiliza super
para invocar al constructor de la superclase desde en constructor de la subclase.

/**
* Este ejemplo muestra el uso del puntero "super" para acceder
* al constructor de la clase padre. Tambien ilustra el uso de
* "super" para resolver la ambiguedad entre las variables
* local y de instancia en la superclase
*/

class base {
int datoBase;

public base() {
System.out.print( "Dentro del Constructor de la clase base" );
System.out.println( "Asignando a datoBase 100" );
datoBase = 100;
}
}

class javasuper extends base {


int datoSubClase;

// Constructor de la Subclase

Docente: Ing. Pedro Beltrán Canessa ~ 10 ~


Universidad Los Ángeles de Chimbote Curso: Técnicas de Programación

public javasuper() {
// Llamada al constructor de la clase base
super();
System.out.print( "Dentro del Constructor de la subclase" );
System.out.println( "Asignando a datoSubClase 200" );
datoSubClase = 200;
}

// Metodo para mostrar como se resuelve la ambiguedad entre


// una variable local y una variable de instancia que tienen
// el mismo nombre
void miMetodo() {
// Se crea una variable local para ocultar la variable de
// instancia de la clase base
int datoBase = 300;

System.out.println( "Dentro del metodo miMetodo" ); System.out.println( "El


valor de la variable Local es " + datoBase ); System.out.println( "El valor de la
variable de Instancia es "+ super.datoBase );
}

public static void main( String args[] ) {


javasuper obj = new javasuper();

System.out.println( "Dentro de main" );


System.out.println( "La variable de instancia en la clase contiene " + obj.datoBase);
System.out.println( "La variable de instancia en la subclase contiene "+obj.datoSubClase);

// Llamada al metodo para mostrar el uso de super en la


// resolucion de la ambiguedad
obj.miMetodo();
}
}

Docente: Ing. Pedro Beltrán Canessa ~ 11 ~

S-ar putea să vă placă și