Java data encapsulation, initializing and postconditions?

1.1k views Asked by At

My assignment is to complete the Date class shown below. The Date class encapsulates a date by storing the month, day, and year in private instance variables.

  public class Date
  {
  // declare your instance variables here
  // postcondition: instance variables are initialized with any valid values
  // you choose
  public Date ()
  {

  }
  // postcondition: instance variables are initialized with the given values if they are valid
  // the month instance variable should be between 1-12
  // the day instance variable should be between 1-31
  // if the parameters are not valid, the instance variables are given different values that are valid
  public Date(int theMonth, int theDay, int theYear)
  {
  }
  // postcondition: returns a String in the form month/day/year
  public String toString()
  {
  }
}

The code below is what I have so far. Frankly, I am pretty confused about what I am supposed to do, and I don't have an instructor to ask. The output is " 2/2/0 "

EDIT UPDATE: If I enter a year that is invalid, such as 200, it does not print the error message... My intention with the if statement was to catch errors where the year is not 4 digits. Is this correct? Thank you for any and all help!

public class Date
{
// declare your instance variables here
private int myMonth;
private int myDay; 
private int myYear;
// postcondition: instance variables are initialized with any valid values

// you choose
public Date ()
{
    myMonth = 11;
    myDay = 11;
    myYear = 2011;
}
// postcondition: instance variables are initialized with the given values if they are valid
// the month instance variable should be between 1-12
// the day instance variable should be between 1-31
// if the parameters are not valid, the instance variables are given different values that are valid
public Date(int theMonth, int theDay, int theYear)
{
   if ( theMonth >= 1 && theMonth <= 12 ) {
       myMonth = theMonth;
   }
   else {
       System.out.print("Month Value invalid; default to 1");
       myMonth = 1;
   }
   if( theDay >= 1 && theDay <= 31 ) {
       myDay = theDay;
   }
   else {
       System.out.print("Day Value invalid; default to 1");
       myDay = 1;
   }
   if( theYear < 4 ) {
       System.out.print("Year Value invalid; default to 2000");
       myYear = 2000;
   }
   else {
   myYear = theYear;
   }
}
   // postcondition: returns a String in the form month/day/year
public String toString()
{
    return myMonth + "/" + myDay + "/" + myYear;
}

public static void main(String [] args)
{
    int theMonth, theDay, theYear;
    theMonth = 2;
    theDay = 2;
    theYear = 200;
    Date date = new Date(theMonth, theDay, theYear);
    date.toString();
    System.out.println(date);
}
}
2

There are 2 answers

6
Mumbleskates On BEST ANSWER

Keep in mind! When you call date.toString(); you aren't converting the entire date variable into a String; since that doesn't actually change anything in the object, that line does nothing.

Fortunately it still works since when you call println(date) with the PrintStream object System.out, you are actually calling the variation of println() that takes an Object as a parameter instead of the one that takes a String, and what that does is get the result of the parameter's toString() method and prints that. So, it's the exact same result in the end.

The real problem is in your constructor method. Look really closely, and read through it. Pretend you are the parameter theYear and your value is 2222. At what point are you going to be used, and how?


spoilers below, seriously go look


You are in fact never setting the field myYear to anything unless the parameter theYear is invalid! The best solution here would be to add that missing else clause after you check theYear to match up with your handling of the rest of the parameters.

2
Sergey Kalinichenko On

You need to fix your implementation in several places:

  • Since you are learning about encapsulation, you should declare your variables private
  • Assuming that there are no other methods in your class, you should also declare your variables final
  • There is no rule asking to validate the year, so the if condition needs to go; assignment of the year needs to be unconditional

This should fix the problem with printing zero instead of the year.

Note: (skip this if you have not studied exceptions yet) a common way to deal with ensuring post-conditions in the constructor is throwing exceptions when the parameters are invalid, rather than trying to guess what these parameters should have been. Consider throwing IllegalArgumentException when you detect that one of the arguments is not valid:

public Date(int theMonth, int theDay, int theYear)
{
   if ( theMonth < 1 || theMonth > 12 ) {
       throw new IllegalArgumentException("month");
   }
   if( theDay < 1 || theDay > 31 ) {
       throw new IllegalArgumentException("day");
   }
   myMonth = theMonth;
   myDay = theDay;
   myYear = theYear;
}