Section 11.5. Creating Accessors (Getters) and Modifiers (Setters)


[Page 363]

11.5. Creating Accessors (Getters) and Modifiers (Setters)

Now we can create a Student object with a name and an array of grades. How do we access the data in the fields? We can access public fields using dot notation: (objectRef.fieldName). We have used this to access the public length field of arrays (gradeArray.length). What happens when we try this with private fields?

> System.out.println(student1.name); java.lang.IllegalAccessException: Class koala.dynamicjava.interpreter.EvaluationVisitor can not access a member of class Student with modifiers "private"   at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:57)   at java.lang.reflect.Field.doSecurityCheck(Field.java:811)   at java.lang.reflect.Field.getFieldAccessor(Field.java:758)   at java.lang.reflect.Field.get(Field.java:228)


If we try to use dot notation to access the private field of an object from outside the class it is declared in, we will get a compiler error. Fields that are declared to be private can only be accessed directly inside of the same class definition. This means that objects of other classes won't be able to access this data directly (using objectRef.fieldName) in the interactions pane.


[Page 364]

11.5.1. Creating Accessors (Getters)

In order to let objects of other classes access the information in private fields, we need to create public methods that access the private fields. Accessors are methods that return private field information. By convention these are declared as:

public type get FieldName()


The method that will return the value of the name is:

public String getName() { return this.name; }


Notice that we put the code for the method on the same line as the method declaration. This is okay for short methods and is often used for accessors. We could also have written this as follows:

public String getName() {    return this.name; }


Should we create a method to return the array of grades? If we return the array, we lose control over it. We could create a method that returns a value from the array for a given index.

public double getGrade(int index) {   return this.gradeArray[index]; }


Computer Science Idea: Protecting Object Data

Objects should protect their data and make sure that it stays in a correct state. One of the ways that objects protect their data is by having private fields and providing public accessors that allow other classes to view the data. But accessors need to be careful that they don't allow objects of other classes to directly modify the data.


11.5.2. Creating Modifiers (Setters)

What if we want to change one of the grades? Since the grade array is private, we can't directly modify it outside of the class definition. If we try to change it directly in the interactions pane, we will get an IllegalAccessException.

> student1.gradeArray[0] = 90; java.lang.IllegalAccessException: Class koala.dynamicjava.interpreter.EvaluationVisitor can not access a member of class Student with modifiers "private"   at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:57)   at java.lang.reflect.Field.doSecurityCheck(Field.java:811)   at java.lang.reflect.Field.getFieldAccessor(Field.java:758)   at java.lang.reflect.Field.get(Field.java:228) >



[Page 365]

But we do need a way to change an incorrect grade. We can do this by asking the object to change the value for a grade. The object can refuse to change the grade and should refuse if the user inputs an invalid value (like -30). Methods that modify fields are called modifiers or mutators. The Java convention is to declare these as follows:

public returnType setFieldName(type param1Name,                                type param2Name, ...)


Here is a method that will try to change the grade stored at a passed index to a passed new grade. If the new grade is less than 0 or the grade array is null, it won't change the grade and will return false. Otherwise it will change the grade and return true. Methods that modify a value can return a boolean to indicate whether the modification was successful or not.

public boolean setGrade(int index, double newGrade) {   if (newGrade < 0 || this.gradeArray == null)     return false;   else   {     this.gradeArray[index] = newGrade;     return true;   } }


If the no argument constructor or the constructor that just takes the name was used to create a Student object, the grade array will be null. We need some way to set it. One way is to pass in the grade array to use. We can decide to only allow this if the grade array is currently null.

public boolean setGradeArray(double[] theArray) {   if (this.gradeArray != null)   {     return false;   }   else   {     this.gradeArray = theArray;     return true;   } }


You can have more than one return statement in a method as shown above. This method could be written with only one return statement as follows:

public boolean setGradeArray(double[] theArray) {   boolean result = false;   // only set the gradeArray if it is null   if (this.gradeArray == null) 
[Page 366]
{ this.gradeArray = theArray; result = true; } return result; }


Which way is better? Both give the same result so the true test is which is easier for another person to understand and change? Beginners often think the first approach is better but the second approach will be easier for another person to understand and change.

Here is a method that will set the student's name only if it is currently null; otherwise it will leave the current name alone. It will return true if the name is changed and false otherwise.

public boolean setName(String theName) {   boolean result = false;   if (this.name == null)   {     this.name = theName;     result = true;   }   return result; }


Why only change the name if it is null? This is a public method, meaning that objects of other classes can invoke this method. Do we want to let objects of classes other than Student change a student's name once it is initially set? In this case we have chosen not to allow this. One of the advantages of object-oriented programming is that the data and methods are encapsulated in the class definition. This means that the data is grouped with the methods that affect it inside of a class. If the data get into an incorrect state, we know that the class isn't doing its job of protecting the data.



Introduction to Computing & Programming Algebra in Java(c) A Multimedia Approach
Introduction to Computing & Programming Algebra in Java(c) A Multimedia Approach
ISBN: N/A
EAN: N/A
Year: 2007
Pages: 191

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net