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.
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
Publicar un comentario