martes, 4 de julio de 2017

Todo sobre: Objetos en Java

Objetos
Un objeto se compone de atributos y métodos. Para acceder a los elementos de un objeto se escribe el nombre del objeto, un punto y el nombre del elemento al que se desea acceder.

Por ejemplo, para los objetos vehiculo1 y vehiculo2, se podría acceder directamente a sus atributos como se muestra a continuación:



Vehiculo vehiculo1 = new Vehiculo("4050 ABJ",
"VW", "GTI",
"Blanco",
100.0);
System.out.println("Matricula : " +
vehiculo1.matricula);
System.out.println("Marca y modelo: " +
vehiculo1.marca + " " +
vehiculo1.modelo);
System.out.println("Color : " +
vehiculo1.color);
System.out.println("Tarifa : " +
vehiculo1.tarifa);

La salida por la consola:
Matrícula : 4050 ABJ
Marca y modelo: VW GTI
Color : Blanco
Tarifa : 100.0

Para acceder a un método, además de su nombre hay que indicar la lista de argumentos requeridos por el método. Cuando la declaración del método no incluye parámetros no es necesario pasar argumentos.

El siguiente código Java crea el objeto vehiculo1 y muestra su matrícula y su tarifa. A continuación modifica la tarifa a 90.0 euros y la muestra de nuevo.

Vehiculo vehiculo1 = new Vehiculo("4050 ABJ",
"VW",
"GTI",
"Blanco",
100.0);
System.out.println("Matricula : " +
vehiculo1.getMatricula());
System.out.println("Tarifa : " +
vehiculo1.getTarifa());
vehiculo1.setTarifa(90.0);
System.out.println("Matricula : " +
vehiculo1.getMatricula());
System.out.println("Tarifa : " +
vehiculo1.getTarifa());

La salida por la consola:
Matrícula : 4050 ABJ
Tarifa : 100.0
Matrícula : 4050 ABJ
Tarifa : 90.0

Para mostrar la tarifa del objeto vehiculo1 se puede acceder directamente al atributo tarifa del objeto o se puede ejecutar el método getTarifa().
Esto se debe a que los atributos de clase Vehiculo son de acceso público porque se han declarado public en vez de private. Los atributos de la clase se deben declarar private y para acceder a ellos se debe utilizar un método ‘get’.


La referencia null
Una referencia a un objeto puede no tener asignada una instancia. Esto puede ocurrir porque se ha declarado el objeto pero no se ha instanciado, es decir no se ha creado un objeto con el operador new. Existe un valor especial, llamado null que indica que un objeto no se ha instanciado. 
A continuación se declara el objeto vehiculo2, pero no se crea una instancia para él.

Vehiculo vehiculo2;

Mientras no se instancie el objeto vehiculo2 su referencia vale null. En un programa Java no se deben dejar referencias de objetos sin instanciar.
Es necesario asegurarse que los objetos existen para evitar referencias null.

El objeto se puede instanciar en la misma declaración o más adelante, como se muestra en el siguiente ejemplo.

Vehiculo vehiculo2;
// el objeto vehiculo2 se declara pero no se instancia
// la instancia se crea utilizando el operador new
Vehiculo vehiculo2 = new Vehiculo("2345 JVM",
"SEAT",
"León",
"Negro",
80.0);

Para saber si una referencia está instanciada o no, se puede comparar con null.

if (vehiculo2 == null) {
System.out.print("vehiculo2 es una referencia null")
}
if (vehiculo2 != null) {
System.out.print("vehiculo2 está instanciado")
}

Si vehiculo2 es null, la primera expresión es true y la segunda false.
En ese caso, el programa muestra por la consola el mensaje:

vehiculo2 es una referencia null


Referencias compartidas por varios objetos
Un objeto puede tener varias referencias o nombres. Un alias es otro nombre que se referencia al mismo objeto. Un alias es una referencia más al mismo espacio de memoria del objeto original. Por ejemplo, si se crea el objeto vehiculo1 y después se declara otro objeto vehiculo3 y a continuación se asigna la referencia de vehiculo1 a vehiculo3, entonces vehiculo3 es un alias de vehiculo1. Esto significa que el espacio de memoria de vehiculo1 y vehiculo3 es el mismo.

Vehiculo vehiculo1;
Vehiculo vehiculo3;
vehiculo1 = new Vehiculo("4050 ABJ",
"VW",
"GTI",
"Blanco",
100.0);
// el objeto vehiculo1 se instancia, vehiculo3 solo
// está declarado y es una referencia null
vehiculo3 = vehiculo1;
// al asignar la referencia de vehiculo1 a vehiculo3,
// éste se convierte en alias de vehiculo1 y referencia
// el mismo espacio de memoria
System.out.println("Matricula : " +
vehiculo1.getMatricula());
System.out.println("Tarifa : " +
vehiculo1.getTarifa());
// se muestra la matricula y la tarifa de vehiculo1
System.out.println("Matricula : " +
vehiculo3.getMatricula());
System.out.println("Tarifa : " +
vehiculo3.getTarifa());
// se muestra la matricula y la tarifa de vehiculo3,
// un alias de vehiculo1, por lo que muestra de nuevo
// la información correspondiente a vehiculo1

La salida por la consola muestra dos veces los valores asignados al objeto
vehiculo1.
Matrícula : 4050 ABJ
Tarifa : 100.0
Matrícula : 4050 ABJ
Tarifa : 100.0

Un alias se puede utilizar para mostrar el estado de un objeto y también para  modificarlo. 

Si se ejecuta setTarifa(90.0) con el objeto vehiculo3 en realidad se modifica la tarifa de vehiculo1. vehiculo3.setTarifa(90.0);

// al modificar la tarifa de vehiculo3 en realidad se
// modifica la tarifa de vehiculo1
System.out.println("Matricula : " +
vehiculo1.getMatricula());
System.out.println("Tarifa : " +
vehiculo1.getTarifa());
System.out.println("Matricula : " +
vehiculo3.getMatricula());
System.out.println("Tarifa : " +
vehiculo3.getTarifa());

Se muestra la matrícula y la tarifa de vehiculo1 y vehiculo3.
Matrícula : 4050 ABJ
Tarifa : 90.0
Matrícula : 4050 ABJ
Tarifa : 90.0

El objeto vehiculo3 es un alias de vehiculo1 y no tiene un espacio de memoria propio. Utiliza el mismo espacio de memoria que vehiculo1. Es decir, vehiculo1 comparte con sus alias el mismo espacio de memoria. Si se modifica el valor de la tarifa almacenada en vehiculo3, en realidad se modifica el valor de vehiculo1.

Esquemáticamente, un alias se puede ver como un objeto que apunta al espacio de memoria de otro objeto, como se muestra a continuación:



En este esquema, el objeto vehiculo3 es un alias de vehiculo1 y ambos objetos comparten el mismo espacio de memoria. El objeto vehiculo2, tiene su espacio de memoria propio y no lo comparte con otro objeto.


El ciclo de vida de un objeto
El ciclo de vida de un objeto empieza por su declaración, su instanciación y su uso en un programa Java hasta que finalmente desaparece.


Cuando un objeto deja de ser utilizado, Java libera la memoria asignada al objeto y la reutiliza. El entorno de ejecución de Java decide cuándo puede reutilizar la memoria de un objeto que ha dejado de ser útil en un programa. El programador no debe preocuparse de liberar la memoria utilizada por los objetos. A este proceso se le conoce como recolección de basura. Java cuenta con un sistema recolector de basura que se encarga de liberar los objetos y los espacios de memoria que ocupan cuando éstos dejan de ser utilizados en un programa.