Skip to main content

Section 3.4 Retrieving Information from an Object

The modifications we've made to the OneRowNim class allow us to set the instance variables of a OneRowNim object with a constructor, but there is no way for us to retrieve their values other than to use the report() method to write a message to the console. We will want to be able to ask a OneRowNim object to provide us with the number of sticks remaining and who plays next when we develop a graphical user interface for OneRowNim in the next chapter. We declared nSticks and player as private variables, so we cannot access them directly. Therefore, we will need accessor methods to get the values of each of the instance variables. Consider the following method definitions:

public int getSticks()
{   return nSticks;
}
public int getPlayer()
{   return player;
}

A method's Result Type or Return Type is specified just in front of the MethodName. We want the two methods to return int values that represent OneRowNim's instance variables. Therefore, their result types are both declared int.

Many methods that return a value do a computation rather than simply returning the value of an instance variable. For example, suppose we wish to define a method for the OneRowNim class that will notify the user of an instance of the class whether the game is over. Thus we want a method that, when called, returns a true or false value depending on whether or not all the sticks have been taken. We can name this method gameOver() and give it a boolean result type. This method should return true when the instance variable nSticks no longer contains a positive int value. Thus we can define:

public boolean gameOver()
{   return (nSticks <= 0);
}

The expression (nSticks <= 0) evaluates to a false value if nSticks stores a positive value and it evaluates to true otherwise. Thus the value returned is precisely what is required.

Subsection 3.4.1 Invoking a Method That Returns a Value

When we invoke a method that returns a value, the invocation expression takes on, or is replaced by, the value that is returned. For example, if we execute the statements

OneRowNim game1 = new OneRowNim(11);
int sticksLeft = game1.getSticks();

the expression game1.getSticks() will take on the value 11 after the getSticks() method is finished executing. At that point, the second statement above can be treated as if expression game1.getSticks() is replaced with the value 11, which is assigned to sticksLeft. In effect, the second statement is equivalent to the following statement:

int sticksLeft = 11;

We can use a value returned by a method call the same way we use a literal value of the same type. It can be assigned to variables, be part of a numerical expression, or be an argument of another method. All of the following statements involve valid calls of methods that return values:

int fewerSticks = game1.getSticks() - 1;
boolean done = game1.gameOver();
System.out.println(game1.getPlayer());
game1.getSticks();

In each statement, the method call can be replaced with the value it returns. Notice that the last statement is valid but does nothing useful. In Java and some other languages like C and C++, methods that return a value can simply be called without making use of the value returned. This may be useful to do if the method changes the state of instance variables or sends a message to another object or an output device. The method getSticks() does nothing but return the value of nSticks, so simply calling the method accomplishes nothing.

Subsection 3.4.2 An Expanded OneRowNimClass

Let's add the new methods that return values to our OneRowNim class. We might note that the report() method from the previous chapter displays the values of nSticks and player in the console window which now could be done by using the methods getSticks() and getPlayer() with System.out.println(). However, calling report() is an easy way to display the values of both instance variables but it cannot provide access to either variable as an int value. So let's keep all three methods in our class definition. The inconvenience of a small amount of redundancy is outweighed by the added flexibility of being able to call all three methods.

Figure 3.4.3 provides a UML class diagram of the expanded OneRowNim class.

Table 3.4.3. A UML class diagram for the expanded OneRowNim.
OneRowNim
\(-\) nSticks: int
\(-\) player: int
\(+\) OneRowNim()
\(+\) OneRowNim(in sticks:int)
\(+\) OneRowNim(in sticks:int,in starter:int)
\(+\) takeSticks(in num:int)
\(+\) getSticks():int
\(+\) getPlayer():int
\(+\) gameOver():boolean
\(+\) report()

Let's also consider a new main() method to test the new methods of the class. A very short list of statements that call each of the three new methods returning values is given in the main() method in Figure 3.4.4

public static void main(String[] args)
{ OneRowNim game = new OneRowNim(13,2);
  game.takeSticks(2);
  System.out.print("The game is over is: ");
  System.out.println(game.gameOver());
  System.out.print("The next turn is by player: ");
  System.out.println(game.getPlayer());
  System.out.print("Sticks remaining: ");
  System.out.println(game.getSticks());
} //main()
Figure 3.4.4. A main() method that tests the new methods for OneRowNim

The output to the console when this program is run will be:

The game is over is: false
The next turn is by player: 1
Sticks remaining: 11

Note that the constructor sets player to 2, so player stores the value 1 after one turn.

Trace through the code in the following activity.

Activity 3.4.1.

Click on Show CodeLens and then the Next button to step through the code.

Exercises Self-Study Exercises

1. Determine Output.

What would these segments of Java code display on the screen?

OneRowNim myGame = new OneRowNim(10,2);
System.out.println(myGame.getPlayer());
System.out.println(2 * myGame.getSticks());
System.out.println(myGame.gameOver());

Suppose that an int instance variable named nMoves is added to the OneRowNim class that counts the number of moves taken in a One Row Nim game. In the active code below or in your own development environment, write a Java method for the OneRowNim class to get the value stored in nMoves. And write a method called playerOneGoesNext() that returns a boolean value. The value returned should be true if and only if player one has the next turn.

2. OneRowNim get Method.

Write a get method that returns the value stored in nMoves. Write a method playerOneGoesNext() that returns a boolean value true if player one has the next turn.

You have attempted of activities on this page.