Foros aprenderaprogramar.com
Aprender a programar => Aprender a programar desde cero => Mensaje iniciado por: cel_i_l en 06 de Noviembre 2021, 18:29
-
Buenas tardes a todos,
Estuve intentando realizar un ejercicio y me quedé atascada, no sé qué debo modificar ni cómo debo seguir. Os agradecería mucho vuestra ayuda, empecé sólo hace un mes el curso. Os paso el enunciado y lo que he hecho hasta ahora:
Ejercicio
Construye un nuevo proyecto Java denominado Prog03_Ejerc1. En el proyecto debe aparecer un paquete, que no puede ser el paquete por defecto, ponle el nombre que creas oportuno. Dentro de dicho paquete:
-Crea una clase denominada Fecha. Esta clase no debe contener método main.
-Declara en el fichero de la clase un tipo enumerado, denominado enumMes, para los meses del año.
-La clase debe contener un atributo para el día, otro para mes (del tipo enumerado declarado) y un tercero para el año.
-Implementa un constructor que inicialice el mes al valor recibido por parámetro y los demás atributos a 0. Observa su cabecera en el siguiente código:
Fecha (enumMes mes){
-Declara otro constructor que inicialice todos los atributos de la clase. Su cabecera podría ser la siguiente:
Fecha (int dia, enumMes mes, int anio){
-Implementa los métodos que permitan acceder y modificar cada uno de los atributos de la clase. Los nombres de dichos métodos serán: getXXX () para obtener el valor del atributo XXX y setXXX (v) para actualizar el atributo XXX con el valor v. Puedes observar la cabecera de algún método en el siguiente código:
public int getDia() {
}
public void setDia(int dia) {
}
-Implementa un método que devuelva true si el valor contenido en la fecha es verano y false en caso contrario. Observa su cabecera en el siguiente código:
public boolean isSummer(){
No es necesario utilizar estructuras condicionales pues aún no las hemos trabajado. Se puede implementar este método utilizando operadores de comparación.
-Implementa un método que devuelva una cadena con la fecha en formato largo, por ejemplo, 15 de julio de 2020. Observa su cabecera:
public String toString (){
Ya tenemos nuestra clase Fecha implementada. Ahora vamos a probar su funcionalidad desde otra clase, denominada Principal, que contendrá el método main. Esta clase la debes crear en el mismo paquete que la clase Fecha. Dentro de dicha clase:
-Instancia un objeto de la clase Fecha denominado objFecha1 con el primer constructor.
-Actualiza los atributos dia y año para dicho objeto.
-Muestra la fecha por pantalla en formato largo.
-Muestra un mensaje por pantalla indicando si la fecha es verano (puedes utilizar el operador de comparación ternario. Punto 5.3 de la Unidad 2).
-Instancia otro objeto de la clase Fecha denomiando objFecha2 con el segundo constructor.
-Muestra el año de esta fecha por pantalla.
-Muestra la fecha en formato largo por pantalla.
-Muestra un mensaje por pantalla indicando si la fecha es verano o no.
Observa un ejemplo de ejecución:
Primera fecha, inicializada con el primer constructor
La fecha es: 20 de febrero del 2000
No es verano
Segunda fecha, inicializada con el segundo constructor
La fecha 2 contiene el año 2015
La fecha es: 15 de julio del 2015
Es verano
BUILD SUCCESSFUL (total time: 0 seconds)
---------------------------------------------------------------------------------------------------
Mi código:
package Time;
import Time.Fecha.enumMes;
import javax.swing.Spring;
public class Fecha {
Fecha() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public enum enumMes {
ENERO, FEBRERO, MARZO, ABRIL, MAYO, JUNIO, JULIO, AGOSTO, SEPTIEMBRE, OCTUBRE, NOVIEMBRE, DICIEMBRE
}
enumMes mes;
int dia;
int anio;
Fecha(enumMes mes){
dia = 0;
anio = 0;
mes = mes;
}
Fecha(int dia, enumMes mes, int anio){
dia = dia;
mes = mes;
anio = anio;
}
public int getDia(){
return dia;
}
public void setDia(int dia){
this.dia = dia;
}
public enumMes getMes(){
return mes;
}
public void setMes(enumMes mes){
this.mes = mes;
}
public int getAnio(){
return anio;
}
public void setAnio(int anio){
this.anio = anio;
}
public boolean isSummer(){
String mes = null;
if ( mes == "Junio" || mes == "Julio" || mes == "Agosto" || mes == "Septimebre" ) { boolean isSummer = true;
}
else { boolean isSummer = false;
}
return false;
}
public String toString(){
return dia + "de"+ mes +"de"+ anio;
}
}
---------------------------------------------------------------------------------------------------
package Time;
import Time.Fecha.enumMes;
public class Principal {
public static void main( String args[] )
{
Fecha objFecha1 = new Fecha();
int dia = 10;
int anio = 2000;
System.out.print("La fecha es: " + dia + "de" + enumMes.ENERO.toString() + "de" + anio);
}
}
---------------------------------------------------------------------------------------------------
Espero vuestras respuestas,
Un saludo y gracias.
-
Algunas cosas a mencionar.
Los atributos, salvo que tengamos algún motivo especial, por regla general se declaran como private
private enumMes mes;
private int dia;
private int anio;
Los constructores, salvo que haya un motivo especial, los declararemos como public
public Fecha(enumMes mes){
dia = 0;
anio = 0;
mes = mes;
}
public Fecha(int dia, enumMes mes, int anio){
dia = dia;
mes = mes;
anio = anio;
}
Eso dos constructores, tienen un problema serio.
No estás usando la palabra reservada this
Si no la usamos, el compilador no sabe distinguir cuando nos referimos al atributo de la clase o al objeto que recibe el constructor, cuando estos tienen el mismo nombre.
Por ejemplo, en este constructor, la linea que señalo en rojo:
public Fecha(enumMes mes){
dia = 0;
anio = 0;
mes = mes;
}
Tu ahí pretendes asignarle al atributo llamado mes, la referencia recibida por paréntesis, que también se llama mes.
Pero Java no sabe que tú quieres referirte al atributo y lo que hace es asignar a la referencia mes, a sí misma... lo cuál es absurdo.
O les das nombres distintos, para que Java sepa a quien te refieres
public Fecha(enumMes otroMes){
dia = 0;
anio = 0;
mes = otroMes;
}
O si no, usa la palabra reservada this para indicar cuándo te refieres al atributo
public Fecha(enumMes mes){
dia = 0;
anio = 0;
this.mes = mes;//A "este mes", le asignamos el "otro mes"
}
El otro constructor, requiere la misma corrección, porque ahora mismo no está asignando nada a los atributos
public Fecha(int dia, enumMes mes, int anio){
this.dia = dia;
this.mes = mes;
this.anio = anio;
}
El método isSummer() está mal, por varios motivos.
Primero, porque da igual lo que se compute, solo hay un return que siempre retorna false
public boolean isSummer(){
String mes = null;
if ( mes == "Junio" || mes == "Julio" || mes == "Agosto" || mes == "Septimebre" ) {
boolean isSummer = true;
}
else {
boolean isSummer = false;
}
return false;
}
En cuanto a lo computa, nunca va a funcionar, porque no se está trabajando con el atributo mes de esta clase Fecha.
Se está trabajando con un String que tiene valor null
public boolean isSummer(){
String mes = null;
if ( mes == "Junio" || mes == "Julio" || mes == "Agosto" || mes == "Septimebre" ) {
boolean isSummer = true;
}
else {
boolean isSummer = false;
}
return false;
}
Hay que hacer comparaciones con el atributo mes de esta clase, que además NO ES UN STRING.
Es un enumerado de tipo enumMes.
Así que hay comparar los enumerados y garantizar que hay un return true y un return false
public boolean isSummer(){
if (mes == enumMes.JUNIO || mes == enumMes.JULIO || mes == enumMes.AGOSTO || mes == enumMes.SEPTIEMBRE)
return true;
else
return false;
}
Sobre el método toString, solo comentar dos mejoras.
Una, es ponerle al principio la etiqueta @Override
No es obligatorio, pero sí muy recomendable ponerla siempre que vamos a sobreescribir un método.
El método toString(), es un método que TODAS las clases Java heredan de la clase Object
Al escribirle un código, estamos sobreescribiendo ese método heredado. Y es muy recomendable señalarlo con la etiqueta Override, para que tanto Java, como otro programador que vaya a leer tu código, inmediatamente sepa que ese método está siendo sobreescrito
La otra mejora es añadir espacios en blanco a las palabras " de ", para que no salga todo junto
@Override
public String toString(){
return dia + " de "+ mes +" de "+ anio;
}
Bueno, ya tendríamos las clase Fecha corregida.
La pongo completa, tal y como la tengo yo ahora:
public class Fecha {
public enum enumMes {
ENERO, FEBRERO, MARZO, ABRIL, MAYO, JUNIO, JULIO, AGOSTO, SEPTIEMBRE, OCTUBRE, NOVIEMBRE, DICIEMBRE
}
private enumMes mes;
private int dia;
private int anio;
public Fecha(enumMes mes){
dia = 0;
anio = 0;
this.mes = mes;
}
public Fecha(int dia, enumMes mes, int anio){
this.dia = dia;
this.mes = mes;
this.anio = anio;
}
public int getDia(){
return dia;
}
public void setDia(int dia){
this.dia = dia;
}
public enumMes getMes(){
return mes;
}
public void setMes(enumMes mes){
this.mes = mes;
}
public int getAnio(){
return anio;
}
public void setAnio(int anio){
this.anio = anio;
}
public boolean isSummer(){
if (mes == enumMes.JUNIO || mes == enumMes.JULIO || mes == enumMes.AGOSTO || mes == enumMes.SEPTIEMBRE)
return true;
else
return false;
}
@Override
public String toString(){
return dia + " de "+ mes +" de "+ anio;
}
}
Vamos a tu main, donde también hay algunos fallos.
El primero es que el objeto Fecha lo inicializas con un constructor que no recibe nada.
El enunciado del ejercicio dice que hay dos constructores, uno recibe el mes y otro recibe todos los datos.
No debería haber ningún constructor que no reciba nada.
Luego, el dia y el año los inicializas en unas variables separadas que no tienen ninguna relación con ese objeto Fecha.
Por cierto, para poder indicarle uno de los meses declarados en enumMes, como este enumerodo está dentro de la clase Fecha, hay que poner primero su nombre.
Fíjate cómo le paso un mes al primer constructor.
public class Principal {
public static void main(String[] args) {
System.out.println("Primera fecha");
//Primer constructor, recibe solo el mes
Fecha objFecha1 = new Fecha(Fecha.enumMes.AGOSTO);
//Configuramos dia y año
objFecha1.setDia(10);
objFecha1.setAnio(2000);
//Mostramos fecha, para esto hemos sobreescrito el método toString() de Fecha
System.out.println(objFecha1);
//Indicamos si es verano o no, usamos operador ternario
System.out.println(objFecha1.isSummer()?"Es verano":"No es verano");
System.out.println("\nSegunda fecha");
//Segundo constructor, recibe todos los datos
Fecha objFecha2 = new Fecha(20, Fecha.enumMes.OCTUBRE, 2021);
//Mostramos solo el año
System.out.println("Año: " + objFecha2.getAnio());
//Fecha completa
System.out.println(objFecha2);
//Comprobamos si es verano
System.out.println(objFecha2.isSummer()?"Es verano":"No es verano");
}
}
Al ejecutar, vemos en pantalla como se muestran las fechas y como se comprueba si son fechas de verano o no:
Primera fecha
10 de AGOSTO de 2000
Es verano
Segunda fecha
Año: 2021
20 de OCTUBRE de 2021
No es verano
Y ya estaría.
Revisa el código y comprueba que entiendes cada línea.
Cualquier cosa que no te haya quedado clara, solo tienes que preguntar.
Un saludo. ;)
-
Jo, muchísimas gracias por la ayuda, de verdad. Lo entendí todo, lo explicaste genial. Sólo tengo una duda:
-¿Qué diferencia hay en utilizar "System.out.println(objFecha1);" y "System.out.println(objFecha1.toString());"? Me sale lo mismo a la hora de mostrarlo. Me gustaría saber la diferencia.
Gracias y un saludo ;)
-
-¿Qué diferencia hay en utilizar "System.out.println(objFecha1);" y "System.out.println(objFecha1.toString());"? Me sale lo mismo a la hora de mostrarlo. Me gustaría saber la diferencia.
Ninguna en este caso.
El método println() siempre espera recibir un String. Si recibe algo distinto, intenta convertirlo por su cuenta a String, y para ello automáticamente invoca el método toString() del objeto que ha recibido, así que no es necesario que lo invoquemos nosotros