26.- Tipos complejos o referencia: Variables atributos.
Ya hemos visto algunas clases de tipos completos o referencia, como la clase String, la clase Punto y las clases Hora.
Hemos visto como la clase Hora y la clase Punto generan objetos que agrupan 2 datos: x e y para la Clase Punto y h y m para la clase Hora; o bien tres datos: h, m y s para la clase HoraHMS. Los objetos formados con estas clases se crean y manipulan con métodos u operadores que se definen en su propia clase.
Los objetos, o variables referencia, para operar con ellos -cambiar el valor de sus atributos, etc- necesitan estar previamente inicializados, como toda variable, de lo contrario origina un error.
Ejemplo;
Punto p; //variable referencia sin inicializar.
p.x =2.43; // error de compilación: variable no iniciada;
otro:
Punto p1 = null;
Punto p2 = p1; // variable referencia con valor null
p2.x = 2.34; // Error de ejecución: NullPointerException
El compilador no es capaz de analizar la tercera instrucción, y es al ejecutar donde da el error.
Las variables referencia se INICIALIZAN con el operedor new:
Punto p = new Punto(0,0); por ejemplo, y entonces si podemos hacer
p.x = 2.43; el atributo x tomará este valor.
Copia y comparación de objetos.
Para obtener una copia de un objeto en un estado determinado de la
ejecución, se debe proceder atributo a atributo. (Al final veremos el método equals para comprobar si las copias son iguales).
Ejemplo:
Punto p1 = new Punto();
p1.x = 3.2; p1.y = -5.1;
Punto p2 = new Punto();
p2.x = p1.x; p2.y = p1.y;
 |
| Esquema de variables atributo que señalan a objetos en el heap |
Cuando se comparan variables de tipo primitivo el operador == da true o
false según sean o no iguales los valores de las variables que se comparan.
Ejemplo:
p1.x==p2.x se obtiene true; • Cuando este operador se aplica a variables de tipo referencia, se comparan
las referencias.
Si se aplica el operador a dos objetos diferentes, aunque los atributos
tengan el mismo valor, el resultado será false.
p1==p2 se obtiene false;
Objeto desreferenciado: gc:
p3 es la referencia de valor null, lo cual dice que no está indicando a ningún objeto. Por lo que elobjeto al que anteriormente estaba indicando queda desreferenciado.
En el caso (1), si hacemos p2==p3 obtenemos true, y si p1 ==p2 obtenemos false En el caso (2), si hacemos p2==p3 obtenemos false, y si p1==p2 obtenemos true.
Para obtener una copia de un objeto en un estado determinado de la ejecución, se debe proceder atributo a atributo: método equals() para comprobar si las copias son iguales, siendo dos objetos distintos.
public boolean equals(Object o){
return o instanceof Punto
&& this.x == ((Punto) o).x
&& this.y == ((Punto) o).y;
}
Para las cadenas de caracteres se utiliza el método compareTo(String st);
Modificador de instanciabilidad static:
Los atributos de una clase se replican en cada ejemplar. Pero a veces es
necesario tener información común a todos los objetos de una clase.
• Ejemplo: la dimensión (número de coordenadas) de los objetos de la clase
es un dato común de todos los objetos de la clase Punto.
• Un atributo de clase o estático es una variable mediante la que es posible
mantener información común a todos los elementos de la clase.
• Se declaran con el modificador static.
• El resto de atributos, por diferenciar, se denominan de instancia.
• Ejemplo:
public class Punto {
double x; // la abscisa, atributo de instancia
double y; // la ordenada, atributo de instancia
static int dimensión = 2;
// la dimensión, atributo de clase
public Punto() {}// El constructor
}
El sistema asigna memoria a los atributos static cuando se carga
código de la clase para su ejecución, sin necesidad de crear ningún
objeto, y se pueden usar citándolas en la forma:
NombreClase.nombreAtributoStatic
Estos atributos continúan en uso hasta que la clase deja de estar cargada
en memoria (normalmente al finalizar el programa que la utiliza).
• Cuando se crean objectos de la clase, los atributos static no se replica
en cada instancia.
• No obstante, Java lo considera también información propia de cada
ejemplar, y se puede acceder a él a través de una referencia al objeto,
con la notación de punto.
Modificadores de visibilidad public, private:
A menudo la estructura de los objetos de una clase es lo suficientemente
compleja como para mantenerla oculta o inaccesible, total o parcialmente.
Por ejemplo, cuando un usuario utiliza un objeto Scanner, lo más práctico y
seguro es que se desentienda de sus detalles internos.
• Los modificadores
private, public
sirven para establecer los permisos de acceso a los atributos de un objeto, de
acuerdo a las siguientes reglas. Sea C una clase de Java:
– Si un atributo de C se ha declarado public, cualquier clase que use objetos de clase C puede acceder a dicho atributo.
• Si un atributo de C se ha declarado private, solamente se puede
acceder a dicho atributo en el código escrito dentro de la propia clase C.
– Por defecto, un atributo es accesible de manera amistosa para las clases
que se encuentran en la misma carpeta y en otros casos que se estudian posteriormente.
Decidir qué atributos se hacen públicos y cuáles privados dependerá del uso que
pretenda el programador para la clase y sus objetos.
• Ejemplo:
En la clase Math se declaran dos atributos public:
public static final double PI = 3.141592653589793;
public static final double E = 2.718281828459045;
En cambio en la clase String los atributos que guardan los caracteres son privados.
• Los atributos públicos aparecen en la interfaz que se genera de la clase.
Organización de clases: paquetes Java:
Las clases predefinidas de Java vienen clasificadas en paquetes
(package): grupos de clases que pueden ser importadas
conjuntamente para ser usadas en un programa.
El paquete java.lang se importa por defecto. Forman parte de este
paquete las clases System, String y Math.
• El resto de paquetes deben importarse explícitamente.
• Ejemplo.
La clase Scanner se encuentra en el paquete java.util.
Para poder usarla en una clase hay que incluir al principio la cláusula
import java.util.*;
Las clases nuevas también se pueden agrupar en un paquete:
– Se escriben en una misma carpeta que tendrá el nombre del paquete,
– Se declara el nombre del paquete al principio del fichero que contiene a cada una de
las clases de dicho paquete.
– En las clases de un mismo paquete el acceso es amistoso (public por defecto).
– Por defecto, Java considera que cualquier clase se encuentra en un mismo paquete
anónimo.
– La instalación del paquete (más allá de la carpeta en la que se encuentra) consiste en
incluir su ubicación en la variable de entorno CLASSPATH del sistema. Java revisa
esta ubicaciones para buscar los paquetes importados.
– BlueJ da facilidades para automatizar la formación de paquetes y su instalación.
Para pequeños programas o aplicaciones puede ser
suficiente escribir las clases relacionadas en un mismo
proyecto (paquete anónimo).
Comentarios
Publicar un comentario