Anda di halaman 1dari 7

ENCAPSULAMIENTO Y VISIBILIDAD

Para un diseo adecuado del software resulta imprescindible un


correcto encapsulamiento del cdigo. El mayor problema reside en
que el software tiende a cambiar con mucha facilidad, (siempre
encontramos mejores formas de resolver un problema) y resulta
imprescindible que estos cambios afecten lo menos posible a otras
partes de cdigo. Pasemos a definir algunos trminos de forma ms
precisa.
Cuando diseamos un software hay dos aspectos que resultan
fundamentales:
Interface: Cmo este software puede ser utilizado.
Implementacin: El cdigo utilizado para resolver los distintos
algoritmos.
El concepto de interfaz se define en Java como los elementos de una
clase que son visibles desde fuera de esta (con visibilidad public). La
implementacin se define creando unos determinados atributos y
escribiendo el cdigo de los diferentes mtodos.
El encapsulamiento consiste en ocultar la implementacin y los
atributos de un objeto, de manera que slo se puede cambiar su
estado mediante ciertas operaciones definidas en el interface del
objeto. Dicho de otra forma, procurar que el interface sea lo ms
independiente posible de la implementacin.
En Java el encapsulamiento est estrechamente relacionado con la
visibilidad. Para indicar la visibilidad de un elemento (tanto atributos
como mtodos) podemos anteceder una de las siguientes palabras
reservadas:
public: accesibles desde cualquier clase.
private: slo son accesibles por la clase actual.
protected: slo por la clase actual, sus descendientes y clases
de nuestro paquete.

<si no indicamos nada> slo son accesibles por clases de


nuestro paquete.

ACCESO A LOS ATRIBUTOS DE LA CLASE


Los atributos de una clase estn estrechamente relacionados con su
implementacin. Por esta razn conviene marcarlos como private e
impedir su acceso desde fuera. De esta forma en un futuro podremos
cambiar la representacin interna del objeto sin alterar su interface.
Aunque en la teora esta afirmacin parece lgica, en la prctica
resulta difcil de seguir. Pensemos en las dos clases que hemos
diseado. En la de los nmeros complejos al haber
puesto private en los atributos no vamos a permitir que acceder la
parte entera e imaginaria del objeto:

class Complejo {
private double real, imaginario;

Lo mismo ocurre con longitud y latitud de una coordenada


geogrfica. Por lo tanto, resulta imposible consultar o modificar esta
informacin desde fuera de la clase. Para solucionar este problema
vamos a utilizar los mtodos getters y setters (obtencin y
establecimiento). Estos mtodos son utilizados para consultar el valor
de un atributo (getter) o para modificarlo (setter). Resulta
imprescindible indicar que tienen una visibilidadpublic para que
puedan ser invocados desde fuera de la clase. Por ejemplo, para el
atributo real escribiramos los mtodos:

public double getReal() {


return real;
}

public void setReal(double real) {


this.real = real;
}
Esta forma de trabajar puede parecer algo engorrosa, pero tiene sus
ventajas:

Como veremos en el siguiente apartado, podemos cambiar la


representacin interna de la clase sin alterar el interface

Verificar que los valores son correctos:

public void setReal(double real) {


if (real>100000) {lanzamos una excepcin}
else this.real= real;
}

Modificar otros aspectos del objeto o lanzar eventos:

public void setReal(double real) {


contadorModificaciones++; //Con fines estadsticos
lanzamos el evento: onComplejoChange
this.real= real;
}
Resulta tan frecuente su utilizacin que Eclipse incorpora una
herramienta para crearlos de forma automtica. Realiza el siguiente
ejercicio para aprender su funcionamiento:

Ejercicio paso a paso: Creacin automticas de getters y setters

1.

En el proyecto Complejos, abre la clase Complejo.

2.
Pulsa con el botn derecho sobre el cdigo y selecciona la
siguiente opcin: con Android Studio Generate.../ Getter and
Setter y con Eclipse Source / Generate Getters and Setters...
3.
Selecciona los dos atributos de la clase y pulsa OK. Vers
cmo se inserta el siguiente cdigo:

public double getReal() {


return real;
}

public void setReal()double real){


this.real = real;
}

public double getImaginario(){


return imaginario;
}

public void setImaginario(double imaginario) {


this.imaginario = imaginario;
}
4.

Pulsa en el botn Guardar

para almacenar el fichero.

Practica: Getters y setters en la clase coordenadas geogrficas

Inserta en la clase GeoPunto los getters y setters necesarios para


acceder a sus atributos.

CAMBIO DE LA REPRESENTACIN INTERNA DE UNA


CLASE
Tras insertar los cuatro mtodos del ejercicio anterior, uno podra
pensar que el resultado es el mismo que si hubiramos
puesto public delante de los dos atributos. No es exactamente as,
imaginemos que ms adelante queremos verificar que la latitud de
un GeoPunto est en el rango [-90, 90], y en caso contrario lanzar una
excepcin. Si los usuarios de la clase acceden directamente al
atributo esto no ser posible. Ms todava, imagina que en un
momento determinado queremos cambiar la representacin interna
de un nmero complejo para utilizar mdulo y fase en lugar de parte
entera y parte imaginaria. Si hemos tenido la precaucin de no
publicar los atributos, ser posible realizar este cambio sin cambiar el
interface de la clase.

class Complejo {
//declaracin de atributos
private double modulo, fase;

//declaracin de constructor
public Complejo(double real, double imaginario) {
modulo = Math.hypot(real, imaginario);
fase = Math.atan2(imaginario, real);
}

//declaracin de mtodos
public double getReal() {
return modulo * Math.cos(fase);
}

Cuando decimos que no cambiamos el interface de la clase,


queremos decir que no hemos modificado ninguna de las llamadas
marcadas como public. Por lo tanto, no tendremos que modificar
ninguna lnea del cdigo que utiliza la clase Complejo. Aunque la
forma interna de trabajar ha cambiado radicalmente. En la nueva
implementacin algunas operaciones son mucho ms rpidas (como
obtener el mdulo), pero otras son mucho ms lentas (como la suma).
Si quieres puedes ver el ejemplo completo de cmo se podra
implementar esta clase en el siguiente fichero.

Practica: Cambio de representacin de la clase coordenadas


geogrficas

Modifica la clase GeoPunto para que los


atributos longitud, latitud sean representados mediante un inten
lugar de con double. Para disponer de una precisin adecuada ahora
representarn millonsimas de grado en lugar de grados. De esta
forma tenemos una representacin ms compacta. Como veremos
ms adelante esta representacin es la utilizada en el API de Google
Maps. IMPORTANTE, el interfaz de la clase ha de permanecer
exactamente igual. Para el constructor puedes utilizar el siguiente
cdigo.

public GeoPunto(double longitud, double latitud) {


this.longitud = (int) (longitud * 1E6);
this.latitud = (int) (latitud * 1E6);

Anda mungkin juga menyukai