RU beehive logo ITEC dept promo banner
ITEC 120
2008spring
ibarland,
jdymacek

homeinfoexamslectureslabshws
RecipeLawsliessyntaxjava.lang docsjava.util docs

lect05a
Introduction to objects: fields
PizzaServer salary

New topics:

Reading (woo-hoo!): Book Chpts 1, 2.

Fields: Adding state to objects

So far, all the methods we've written could be asked of any object: if we made ten different PizzaServers, we could ask any of them pizzaArea(20) and always get the same answer. (Likewise for EmCees, EBayExperts, etc.) Which means it's rather odd to even have the notion of several different PizzaServer objects: we can't do anything with five PizzaServers which we couldn't do with just one.

However, if you've been paying close attention, we have seen a case where different objects, when asked the same question, can give different answers:

String firstName = "Ian";      // Declare *and* initialize a local var, together.
String lastName  = "Barland";

firstName.substring(0,1)       // Will return "I".
lastName.substring(0,1)        // Will return "B".
This is unsurprising in the context of “you walk up to a particular String and ask it a question”. But, it's something we haven't seen how write ourselves: we can make twenty different PizzaServers, and they'll all answer every question identically. Today we'll see how to let each PizzaServers have its own individual state (internal information), as well as knowing how to answer certain questions.

In addition to being area-calculating-wizards, another important facet of being a PizzaServer is having a salary. We want to say that new PizzaServers start at minimum wage, (although their salary might be set to be higher later on). The Bluej object-inspector window

class PizzaServer {
  
  // Named constants omitted...

  double salary = 5.75;  // Salary, in $/hr.

  // Code for methods omitted...
  }
We say that salary is a field of PizzaServer. (Note that salary is not a local variable! For starters, it's not declared inside of function. We'll talk about the difference more, later.) Let's look at BlueJ: We can make a new PizzaServer as usual, and give it a name like jo or PizzaSer1. This time, we'll explore a different BlueJ button though: we'll right-click on jo and choose Inspect. A box appears, and it shows jo knows her own salary. This small inspector window is a zoom-in1 of the object on the bench.


Setter methods

Okay, great — now every PizzaServer has a salary (in addition to being able to be asked a bunch of area-calculation questions). If we make twenty PizzaServers, we'll still have twenty objects which all look the same — they all make minimum wage. It turns out, we can make a method which modifies a PizzaServer's salary:

/** Set this PizzaServer's salary.
 * @param newSalary the new salary for this PizzaServer (in $/hr).
 */
void setSalary( double newSalary ) {
  this.salary = newSalary;    // Overwrite the field's old value with a new one.
  }
Inspecting a modified PizzaServer First let's call this method, then we'll come back and discuss it more.

Let's make a two PizzaServers, called (say) jo and mo, bring up inspector windows for both of them, and then call jo.setSalary(6.50);. (Note that in the Code Pad, we need to include the semicolon here, because there is no answer coming back from setSalary; it is simply doing something.) We see that jo's salary indeed changes, while mo's salary stays the same. What if we make a new, third PizzaServer — what do you think their salary will be? Why?

setSalary is called a setter method for the field salary.

Edict of programming: Edict of programming: For each field, have a setter and getter method (as appropriate).


Returning nothing: void

The purpose of setSalary is different from any function we've seen before: it's duty is not to return an answer, but instead to change a PizzaServer's state. There are three new things to notice:

Note that technically, void is not some sort of degenerate type, and the function is not actively returning some sort of void-value4. Rather, void is a special keyword which just replaces the return-type in our mantra about declaring a method.

Note: the documentation for a getter and setter are fairly rote:

/** Return this Floobar's numHooshaloomps.
 * @return this Floobar's numHooshaloomps.
 */
int getNumHooshaloomps() { 
                  
  }

/** Set this Floobar's numHooshaloomps.
 * @param newNumH The new value for this Floobar's numHooshaloomps.
 */
                 setNumHooshaloomps(                  ) {
                  .                 =                 ;
  }

Syntax for fields

Our new syntax:

class-declaration ::=
class nameClass {
  field-declarations...

  method-declarations...
  }
where field-declarations look the same as declaring-and-initializing a local variable except for where they occur inside the class-declaration:
field-declaration ::=
type namefield = expression;

Practice Suppose that in addition to having a salary, PizzaServers also get their paycheck put into a bank account. With a partner, add a field balance, which is initialized to 0. Write setBalance, a setter method for that field.
Note that later, we'll write methods for actually paying a PizzaServer depending on how many hours they've worked; right now we simply write the setter method which we'll use in the future.

Fields are not local variables

When to use a field, and when to use a local variable?
Only use a field to represent state which belongs to the object. For instance, a PizzaServer's salary or bank balance or whether they're a manager or their hair color (if such things matter to your program).

Do not use fields just so you can have a variable which spans two methods. For instance, don't make diam a field of PizzaServer, just because you want crustArea to not have to bother passing an input to pizzaArea.
If you need to use a value from one method in another method, use parameters to pass that value in.

A technicality: We could declare a local variable on one line, and then initialize it on the next line. However, Java doesn't allow us to do that with fields — you can't have a line of (initialization) code which isn't inside some method. Tomorrow, we'll see constructor methods — special method for initializing fields5. This technicality isn't anything inherent, it's just a good practice which Java decided to enforce. Conceivably other object-oriented languages could allow initialization statements (using if, for example) to follow the class definition, outside of any method.

Getter methods

We've seen how to use BlueJ's Inspect option on objects, so that we can see the state of an object. But how can you do this from inside your program? We'll make getter methods, for any information which the object is willing to share with people who ask it:

/** A getter for salary.
 * @return this PizzaServer's salary, in $/hr.
 */
double getSalary() {
  return this.salary;
  }
Note that the javadoc for setters and getters can be quite brief (but they still need to be there).

Note that most code will call the getter and a setter for a field, rather than access it directly. After all, it's a bit rude, to reach into a PizzaServer directly and look at or change their salary; instead it's polite to ask them what their salary is. The only functions which will refer directly to a field are, the getter, the setter, and sometimes constructors (a type of method which we'll talk about later this week, whose job is to initialize all fields). Issues of politeness aside, can you give some reasons why it's a good software practice, to always use getters and setters? (Hint: What future changes might be made, which would require only one change to the code if getters/setters are used, and many changes if other code was accessing/changing the field willy-nilly?)

Practice: Write a method

/** Calculate how much would this PizzaServer earn this week, for a given number of hours?
 * @param proposedHours A number of weekly hours of work being considered.
 * @return how much would this PizzaServer earn, if they worked for proposedHours?  (In $.)
 *  Note: this does not change the PizzaServer's state.
 */




Optional challenge: Implement time-and-a-half, if they work more than 40hrs/wk.


1 I wish and that it would draw dashed lines from the window to the bench, to show this connection. Alas, windowing systems don't really let you draw something that's not inside one window. Still, at least BlueJ could border the inspector window red.      

2And, all other fields are unchanged, and all other objects have not changed their state. Whew! Specifying correctness suddenly is much more involved, than when we just had nice, self-contained functions!      

3It's a technical Java distinction: Anything with a semicolon is a statement, not an expression. So:

Sigh; deep-down, Java's specification doesn't allow you to substitute equal expressions for each other.      

4 Other programming languages, striving to be more uniform, do have a void-value which isn't a useful datum, but does allow every function to always return something.      

5 So in Java, if you declare a field, you must either

     

homeinfoexamslectureslabshws
RecipeLawsliessyntaxjava.lang docsjava.util docs


©2008, Ian Barland, Radford University
Last modified 2008.Feb.13 (Wed)
Please mail any suggestions
(incl. typos, broken links)
to iba�rlandrad�ford.edu
Powered by PLT Scheme