2.5. Methods that Return Values¶
All the methods on Turtle
that we’ve discussed so far have had a void
return type. Such methods are sometimes called void methods. Because a
void
method doesn’t return any value, the only point of calling one is
because it does something that can be observed by the user or by other code—it
changes the state of the object or maybe causes something to happen like drawing
a line on the screen. Or both. These things they do are sometimes called
“effects”.
In contrast, methods with a return type of anything other than void
are
called non-void methods. These methods return a value that the code
calling the method can use. And because methods are called on an object, these
methods can be used to return values that tell us things about an object’s
internal state.
In well-designed programs, non-void methods typically don’t have effects; they just compute and return a value. And void methods obviously can’t return values. So most methods are of one kind or the other: either a void method which is called for some effect or a non-void method that is called to compute a value but otherwise has no effect. To put it another way, void methods do things while non-void methods produce values.
2.5.1. Accessors / Getters¶
A simple kind of method that returns a value is what is formally called an
accessor because it accesses a value in an object. In the real world
everyone calls them getters. A getter is a method that takes no arguments
and has a non-void
return type. In Java they are almost always named
something that starts with get
, and they usually just return the value of one
of the object’s instance variables. For example, the Turtle
class has
several getters, getWidth
and getHeight
which return the width and the
height of a Turtle
object and getXPos
and getYPos
which return the x
and y values of the Turtle
’s position.
That means that after you construct a Turtle
, either at the default position
in the middle of the World
or by specifying a starting point as arguments to
the constructor, you don’t need to keep track of where you put it; you can
always get its current position with the getXPos
and getYPos
getters.
Better yet, after creating a Turtle
and moving it all around with the
forward
and turn
methods we discussed in the previous section, you don’t
have to figure out where it ended up; you can just ask it for its new position,
again with the getXPos
and getYPos
getters.
Note that when you use a getter, you need to do something with the value it returns. You might assign it to a variable, use it in an expression, or print it out. If you don’t, you’re just getting a value and doing nothing with it—you might as well not have bothered to call the getter in the first place.
Here are some examples of using getters on the Turtle
object yertle
.
Turtle yertle = new Turtle(world);
int width = yertle.getWidth();
int height = yertle.getHeight();
System.out.println("Yertle's width is: " + width);
System.out.println("Yertle's height is: " + height);
System.out.println("Yertle's x position is: " + yertle.getXPos() );
System.out.println("Yertle's y position is: " + yertle.getYPos() );
Note
A common error is forgetting to do something with the value returned from a method. When you call a method that returns a value, you should do something with that value like assigning it to a variable or printing it out.
Try the code below that creates a turtle and moves it around a bit. Can you confirm that its new position matches what you’d expect given the movements it made? Try changing where it moves to make sure.
(If the code below does not work in your browser, you can also copy in the code below into the Turtle code at this replit.com link (refresh page after forking and if it gets stuck) or download the files here to use in your own IDE.)
Fix the errors in the code below so that it prints out the area of the space that the turtle occupies by multiplying its width and height. Remember that you have to do something with the values that the get methods return.
Try some of the Turtle
getters in the program below. Remember that you
have to print out the values the getters return in order to see them!
Calling a getter just gets a value; it’s up to you to do something with it.
2.5.2. Methods with Arguments and a Return Value¶
Since getters take no arguments, all they can do is return a value based on the current state of the object. But often it’s useful to have methods that compute values based on both the current state of the object and some arguments.
For example, while we could use a Turtle
’s getXPos
and getYPos
getters and some math (remember your Pythagorean Theorem?) to figure out how far
away a Turtle
is from any given point, if that’s a thing we need to do in
a lot of programs using Turtle
, it might be nice to be able to ask a
Turtle
directly for its distance from a given point. After all, it knows
where it is, so why not do the math for us?
And indeed, the Turtle
class has a method called getDistance
that takes
two int
arguments representing an x value and a y value and returns the
distance between the Turtle
’s current position and that x,y point. This
is not a getter because it doesn’t just get an existing value; it computes a new
value based on the arguments it is passed as well as the state of the Turtle
.
Methods that take arguments and return values are somewhat like mathematical
functions. Given some input, they return a value. (Mathematicians expect that a
function always returns the same value, given the same arguments. So they would
not consider something like getDistance(x, y)
a true function since its
return value also depends on the current position of the Turtle
. But we’re
doing programming, not math.)
We will save a deeper discussion of actually writing getters and other methods until Unit 5, but for the AP progress checks for this unit, you should be able to trace through method calls like the ones below. Notice that the return statement in a method returns the value, and it must match declared return type of the method. The calling method must then do something useful with that value.
- 0
- First, call the constructor, then call getArea().
- 314.159
- Correct! getArea() returns 3.14159 * radius * radius, where radius is set to 10 by the constructor.
- c.getArea()
- c.getArea() is a method call, not a value.
- The code will not compile.
- The code does compile.
- 100.0
- Don't forget to multiply by 3.14159.
2-5-4: Consider the following class definition.
public class Circle
{
private double radius;
public Circle(double r)
{
radius = r;
}
public double getArea()
{
return 3.14159 * radius * radius;
}
}
Assume that the following code segment appears in a main method.
Circle c = new Circle(10);
System.out.println(c.getArea());
What is printed as a result of executing the code segment? (If you get stuck, try this visualization to see this code in action.)
- 150
- Note that the method resize() is called before getArea().
- 150.0
- Note that the method resize() is called before getArea().
- 225
- Correct! resize() increases the width by 5, so the area is 15 * 15 = 225.
- 255.0
- Note that getArea() returns an int
- 0
- Note that the constructor initializes width and height.
2-5-5: Consider the following class definition.
public class Rectangle
{
private int width;
private int height;
public Rectangle(int w, int h)
{
width = w;
height = h;
}
public void resize(int amt)
{
width += amt;
}
public int getArea()
{
return width * height;
}
}
Assume that the following code segment appears in a main method.
Rectangle r = new Rectangle(10, 15);
r.resize(5);
System.out.println(r.getArea());
What is printed as a result of executing the code segment? (If you get stuck, try this visualization to see this code in action.)
- 5
- Make sure you call both methods and compute the square of 2 and then add the results.
- 7
- Yes, square(2) returns 4 which is added to divide(6,2) which returns 3. The total of 4 + 3 is 7.
- 4 3
- Make sure you add the results before printing it out.
- 2 3
- Make sure you square(2) and add the results before printing it out.
- Does not compile.
- Try the code in an active code window.
2-5-6: What does the following code print out? (If you get stuck, try this visualization to see this code in action.)
public class MethodTrace
{
public int square(int x)
{
return x * x;
}
public int divide(int x, int y)
{
return x / y;
}
public static void main(String[] args)
{
MethodTrace traceObj = new MethodTrace();
System.out.println(traceObj.square(2) + traceObj.divide(6, 2));
}
}
2.5.3. Programming Challenge : Turtle Distances¶
As we mentioned above,
Turtle
class has a method calledgetDistance(x,y)
which will return the turtle’s distance from a point (x,y). Can you find yertle’s distance from the point (0,0)?Add another turtle and make both turtles move. Then find the distance between them. You must use the
getXPos
andgetYPos
methods as well as thegetDistance
method.
Use the getXPos
, getYPos
, and getDistance(x,y)
methods to find yertle’s distance from the point (0,0). Add another turtle, move both turtles to different positions, and find the distance between the two turtles.
2.5.4. Summary¶
Non-void methods are methods that return values.
Non-void methods typically do not have effects, and are called purely for the value they return.
It is up to the caller of a non-void method to do something with the return value, such as assigning it to a variable or using it as part of an expression.
The value returned by a method has to match the declared return type of the method. Thus it can only be used where a value of that type is allowed, such as being assigned to a variable of that type. data type must match the return type of the method.
2.5.5. AP Practice¶
int result = calculatePizzaBoxes(45, 9.0);
-
The method calculatePizzaBoxes returns a double value that cannot be saved into an int variable.
double result = calculatePizzaBoxes(45.0, 9.0);
-
The method calculatePizzaBoxes has an int parameter that cannot hold a double value 45.0.
int result = calculatePizzaBoxes(45.0, 9);
-
The method calculatePizzaBoxes has an int parameter that cannot hold a double value 45.0. Note that the int 9 can be passed into a double parameter.
double result = calculatePizzaBoxes(45, 9.0);
-
The method calculatePizzaBoxes has an int and a double parameter and returns a double result.
result = calculatePizzaBoxes(45, 9);
-
The variable result has not been declared (with an appropriate data type).
2-5-8: Consider the following method.
public double calculatePizzaBoxes(int numOfPeople, double slicesPerBox)
{ /*implementation not shown */}
Which of the following lines of code, if located in a method in the same class as calculatePizzaBoxes, will compile without an error?
-10
-
The Liquid() constructor sets the currentTemp instance variable to 50 and the lowerTemp() method subtracts 10 from it.
50
-
The Liquid() constructor sets the currentTemp instance variable to 50 and the lowerTemp() method subtracts 10 from it.
water.getTemp()
-
The System.out.println will print the value returned from water.getTemp().
The code will not compile.
-
This code should compile.
40.0
-
Correct, the Liquid() constructor sets the currentTemp instance variable to 50, and the lowerTemp() method subtracts 10 from it, and getTemp() returns the currentTemp value as a double.
2-5-9: Consider the following class definition.
public class Liquid
{
private double boilingPoint;
private double freezingPoint;
private double currentTemp;
public Liquid()
{
currentTemp = 50;
}
public void lowerTemp()
{
currentTemp -= 10;
}
public double getTemp()
{
return currentTemp;
}
}
Assume that the following code segment appears in a class other than Liquid.
Liquid water = new Liquid();
water.lowerTemp();
System.out.println(water.getTemp());
What is printed as a result of executing the code segment? (If you get stuck, try this visualization to see this code in action.)