POO (Programación Orientada a Objetos), static, final y clases en Java – 2

En esta segunda parte de programación orientada a objetos con Java, continuaremos con el ejemplo del post anterior.

 (Haz clic en las imágenes si no son muy claras)

En esta ocasión, vamos a añadir un método para calcular la edad del estudiante, y lo haremos utilizando la palabra reservada “public”, de la misma manera que lo hemos hecho con los getters, setters y constructores. De esta forma, podremos acceder al método desde fuera de la clase. También añadiremos dos atributos, “edad” y “anioActual”, ambos de tipo privado. 


Con respecto a las dos nuevas variables, “anioActual” no tiene getter o setter, ya que no los vamos a necesitar. Esta variable solo será llamada dentro de la clase y no va a cambiar su valor. Por el contrario, edad cuenta con getter y setter por que cambiará su valor al llamar al método “calcularEdad()” y será llamada desde fuera de la clase para imprimir su valor.

El método “calcularEdad()” recibirá un parámetro de tipo “Integer” llamado “anioNacimiento”, que representará el año de nacimiento del estudiante. En el cuerpo del método, se restará el valor del atributo “anioNacimiento” al valor del parámetro “anioActual”, y se almacenará el resultado en una variable llamada “edad”. Finalmente, se asignará el valor de “edad”, variable temporal, al atributo “edad” de la clase utilizando la palabra clave “this”.

Si el uso de la palabra “this” resulta confuso, basta con entender que se utiliza para hacer referencia a las variables que pertenecen a la clase “Estudiante”. Por otro lado, la variable “edad” que se utiliza sin “this” es una variable temporal dentro del método “calcularEdad()”, que se utiliza únicamente para almacenar el resultado de la operación de resta y luego asignarla a la que usa “this”.

Como última aclaración de este punto, las variables de clase, las que usan “this” para ser llamadas, se muestran en color azul en el caso de eclipse y el resto de variables, incluido métodos, se muestran en color marrón.

Hasta ahora, hemos reforzado los conceptos aprendidos en el post anterior, pero ¿para qué nos sirve este nuevo método? ¿En qué casos podemos utilizarlo?

En primer lugar, vamos a analizar las instancias de clase. Cuando creamos un objeto de la clase “Estudiante”, el atributo “anioActual” se inicializa automáticamente con el valor 2023, ya que así lo hemos establecido al declararlo en la clase. En cambio, el atributo “edad” no tiene ningún  valor asignado, ya que no lo hemos establecido en el constructor ni en ningún otro lugar de la clase. La única forma de obtener la edad del estudiante es llamando a su método “calcularEdad()”.

En la clase “App”, ya teníamos instanciados dos objetos “estudiante” y “estudiante2”. Si intentamos imprimir su edad, veremos que aparece la palabra “null”, lo que indica que el valor es nulo. Por lo tanto, debemos llamar al método “calcularEdad()” de cada instancia y pasarles los parámetros “1990” y “1995” respectivamente. Luego, podremos imprimir los resultados utilizando la clase “System” y observar las edades.


final

Nuestro método funciona correctamente, ya que es de tipo “public” y puede ser accedido desde fuera de la clase. Sin embargo, podemos mejorar el código utilizando la palabra reservada “final”. Esta palabra solo permite asignar un valor a un atributo una vez, convirtiéndolo en una constante. Por ejemplo, podríamos declarar el atributo “anioActual” de la siguiente manera: “private final Integer ANIOACTUAL = 2023”. Al ser una constante, conviene escribir el nombre del atributo en mayúsculas para seguir las convenciones de codificación o, en palabras que probablemente has escuchado, seguir las buenas prácticas.

Para ilustrar mejor esto, veamos el error que muestra eclipse cuando se intenta cambiar el valor de una variable declarada con el modificador “final”.

1.       Crea una variable con el modificador “final”, de tipo “String”, de nombre “saludo”, con el valor “Hola Java”.

2.       Llama a la variable saludo e intenta asignarle otro valor.

Si has seguido los dos pasos anteriores debes haber observado un subrayado rojo sobre la variable “saludo”. Si ubicas el cursor encima de la variable verás en error que muestra el eclipse.


Por si tienes te has informado por otro medio, la palabra “final” también puede ser usada en los métodos de forma que se evita la anulación del mismo método cuando se intenta instanciar la clase que lo contiene o se puede declarar una clase con “final” para evitar que sea heredada por otra clase. Sin embargo, estos usos son más complejos y requiere conocimientos de herencia o ejemplos más complejos. Ten presente que detallaré estos usos más adelante y por ahora no te preocupes.

static

Comprendido el modificador anterior, ahora vamos a ver el uso de la palabra clave “static”. Esta palabra se refiere a la clase en sí misma, no a las instancias de clase. Si una variable o método es declarado como estático, todas las instancias de la clase compartirán esa misma propiedad.

En otras palabras, cuando se crean instancias de una clase cada una de ellas tiene sus propias propiedades no estáticas que pueden ser modificadas independientemente. Por ejemplo, en el caso de nuestras instancias “estudiante” y “estudiante1” de la clase “Estudiante”, cada una tiene el mismo atributo no estático “nombre” con diferente valor.

Sin embargo, si una variable es declarada como estática, supongamos que lo es la variable “universidad”, esta pertenece a la clase en sí misma, no a cada instancia. Si se modifica la variable estática, afectará a todas las instancias de la clase y tendrán la misma universidad.

Te invito a hacer lo anterior y comprobar el resultado. Para hacerlo, agrega la palabra “static” después de “private” a la variable “universidad en la clase “Estudiante”. Automáticamente debería estar en cursiva si estás utilizando eclipse. Imprime la universidad de cada estudiante con la clase “System”, como en la imagen siguiente, y ejecuta el código.


Cuando la ejecución del código se encuentra en la línea 5 se asigna el valor “UNFV” a la variable “universidad” por medio de la instancia “estudiante”. En la línea 6, se asigna el valor “Universidad FAS” a la variable “universidad” por medio de la instancia “estudiante1”, lo cual afecta a la instancia ya creada, “estudiante”. Como resultado, se obtiene un mismo valor de universidad para ambas instancias.

Recuerda, la variable estática afecta a la clase, no solo al objeto que la modifica y, como los objetos vienen de la clase, todos resultan afectados.

Bien, hagamos una última prueba para verificar lo anterior. Antes del primer “System.out.println()”, agrega alguna instrucción que modifique la universidad nuevamente. Puede ser por medio del método “setUniveridad()” de cualquiera de las instancias. No olvides pasarle el valor de universidad que deseas guardar como parámetro, y revisa la clase estudiante si no está clara la razón.


Como se observa en la imagen, nuevamente cambió la universidad para ambas variables. Es importante eliminar código que no se usado en una aplicación. Sin embargo, con fines de aprendizaje puedes dejar líneas como la 8 y 9 para recordar lo que has visto.

Resolviendo la tarea de Monty: Agregar la clase “Mascota” como argumento de la clase “Estudiante”

Al finalizar la primera parte del post de programación orientada a objetos, se dio un ejemplo en el que “Monty”, nuestro amigo, elaboró una plantilla “Mascota” con tres datos a ser llenados:

Mascota:

-          Tipo:

-          Nombre:

-          Años:

Si utilizamos nuestro concepto de clase en Java, nos percatamos que “Mascota” puede ser representada como una clase y, como propuso Monty, puede ser agregada a la clase estudiante. De esta forma cada objeto (instancia) de la clase “Estudiante” también podrá agregar datos de su mascota.

Voy a realizar paso por paso esta actividad, pero a estas alturas deberías tener una noción de lo que debes hacer. Siéntete libre de intentarlo por tu cuenta y luego vuelve a este punto, para comparar resultados.

Primero, crearemos la clase “Mascota” con los atributos de la plantilla y un constructor sin argumentos.



Si no recuerdas como crear una clase, agregar los métodos getter y setter o el constructor, regresa al post anterior, la parte 1 de POO (Programación Orientada a Objetos).

Luego, se agrega la variable “mascota” de Tipo “Mascota”, en la clase “Estudiante” con sus respectivo getter y setter.


 

Ahora sí, en el cuerpo del método “main()” en la clase “App” podemos agregar los valores para la mascota de cada estudiante y luego imprimirlos con la clase “System”. 


Para asignar los valores de la clase “Mascota”, es fundamental comprender su funcionamiento. Por ejemplo, para utilizar la clase “Mascota” como un objeto es necesario instanciarla. En el caso de los estudiantes, inicialmente su variable de tipo “Mascota” es nula, lo que significa que no tiene ningún valor. Por lo tanto, es necesario llamar al método “setMascota()” de cada estudiante y pasarle como parámetro una instancia de la clase “Mascota”. Recuerda que, para crear esta instancia, se utiliza la palabra reservada “new”, tal como se muestra en las líneas 13 y 14 de la imagen anterior.

En la línea 16, cada estudiante ya tiene un objeto de tipo “Mascota” en su variable “mascota”, pero aún no tienen ningún valor para sus atributos. Para agregar lo valores correspondientes, se llama al método “getMascota()” de cada estudiante y luego al método setter de cada atributo que se desea agregar.

¡Bien hecho! Ahora tienes una comprensión sólida de los conceptos, el siguiente paso es practicar tanto como puedas y, si es posible, enseñar a otros. De esta manera, podrás fortalecer tus habilidades rápidamente. Te sugiero hacer cambios en el código a tu gusto y poner en práctica todo lo que has aprendido hasta ahora. 

Comentarios

Entradas populares de este blog

Instalación del IDE Eclipse para Java y JShell

POO (Programación Orientada a Objetos), public, private y clases en Java - 1

Instalación de java y manejo de versiones