With the previous class declaration for a date, the fields of an object are directly accessible from a client, i.e., a program like NoelProg can refer to the day field of the object pointed to by tNoelDate by using tNoelDate.day. It can do this because, in the class declaration, the fields have a public modifier, e.g.:
public int day;
Back in the real world, when you want to get off a bus, you usually indicate this by signalling to the bus driver in some way, e.g., by pressing a button that rings a bell. Giving everyone a brake pedal would not be a good idea! In the same way, it is unusual to expose the fields of an object to a client. Instead of making a field public, we will make it private and usually we will provide some methods to allow access to the field. Such methods are called access methods.
So in the following class declaration for Date the three fields for year, month and day have been made private:
private int iYear; private int iMonth; private int iDay;At the same time, the names of these fields have been changed. In this Guide, the i prefix will be used for entities that are internal to a class. You can also remember the meaning of i because it is also a letter of the words hidden and private.
0288: // A class for representing values that are dates. // Date.java
0289: public class Date
0290: {
0291: private int iYear;
0292: private int iMonth;
0293: private int iDay;
0294: public Date(final int pYear, final int pMonth, final int pDay)
0295: {
0296: iYear = pYear;
0297: iMonth = pMonth;
0298: iDay = pDay;
0299: }
0300: public int getYear()
0301: {
0302: return iYear;
0303: }
0304: public int getMonth()
0305: {
0306: return iMonth;
0307: }
0308: public int getDay()
0309: {
0310: return iDay;
0311: }
0312: public void setYear(final int pYear)
0313: {
0314: iYear = pYear;
0315: }
0316: public void setMonth(final int pMonth)
0317: {
0318: iMonth = pMonth;
0319: }
0320: public void setDay(final int pDay)
0321: {
0322: iDay = pDay;
0323: }
0324: public String toString()
0325: {
0326: return iYear + "-" + iMonth/10 + iMonth%10 + "-" + iDay/10 + iDay%10;
0327: }
0328: }
The above class declaration also provides six access methods called getYear, getMonth, getDay, setYear, setMonth and setDay. Two of these are used by the following version of the NoelProg program:
0329: // This program creates an object of class Date // NoelProg.java
0330: // representing Christmas Day 1999, then moves the
0331: // day component on by 1, and then outputs the new date.
0332: public class NoelProg
0333: {
0334: public static void main(final String[] pArgs)
0335: {
0336: final Date tNoelDate = new Date(1999, 12, 25);
0337: final int tDay = tNoelDate.getDay();
0338: tNoelDate.setDay(tDay + 1);
0339: System.out.println(tNoelDate.toString());
0340: System.out.println(tNoelDate);
0341: }
0342: }
0343:
When the program calls getDay as in
tNoelDate.getDay(),
the block of getDay will execute the statement:
return iDay;So the value of the iDay field of the object that is the target of the method invocation is returned. In the case of the NoelProg program, getDay is being applied to the object pointed to by tNoelDate, and the method returns the value of its iDay field. So, 25 gets returned.
In the next statement, the program executes:
tNoelDate.setDay(tDay + 1);So pDay (the parameter of setDay) is assigned the value 26 and this value is used in the block of setDay to change iDay to 26. Once again, the object pointed to by tNoelDate is the target of this call and so it is this object's iDay field that is changed to 26.
The technique of hiding fields behind access methods is an important one. It is called data encapsulation (or information hiding). If you look at the WWW pages for the Core APIs you will find very few classes that have public fields. Possibly the only ones are in the classes java.awt.Point and java.awt.Rectangle.
Although in Stage B2, we found it useful to introduce a method (display) which uses println to display the value of a Date object, in Java it is more usual:
So, instead of having a method called display that calls println, the version of the class Date given above declares a method called toString that just returns a string that NoelProg passes as an argument to println:
System.out.println(tNoelDate.toString());When toString gets called, it just executes:
return iYear + "-" + iMonth/10 + iMonth%10 + "-" + iDay/10 + iDay%10;You can see that the result type of toString is the type String. So the execution of this return statement forms a string consisting of the concatenation of the iYear field of tNoelDate, a hyphen, the two digits of the iMonth field of tNoelDate, another hyphen, and then the two digits of the iDay field of tNoelDate, e.g., "1999-12-25". This is the string that NoelProg passes as an argument to println.
It is usual to call this method toString. The reason for this is that the statement:
System.out.println(tNoelDate.toString());can be abbreviated to:
System.out.println(tNoelDate);This is because both print and println are defined so that if a variable of a reference type is passed as an argument then that type's toString method is called.