Peter Andreae Computer Science Victoria University of Wellington Copyright: Peter Andreae, Victoria University of Wellington Methods Calling Methods Return values COMP 102 #7 2013
© Peter Andreae COMP102 7:2 Menu printf: printing text with format control Methods that call other methods in the same program Methods that return values Administrivia: Getting online help.
© Peter Andreae COMP102 7:3 Designing very simple programs 1.Identify the problem that the program must solve. 2.Decide what methods are needed: What are the different actions the program must perform? 3.Decide on good names for the methods 4.Decide what information each method needs: list the parameter types and give them names 5.Decide what steps each method must do. First describe in English Then in Java. 6.Identify variables needed to store intermediate values 7.Work out expressions for computing values 8.Work out method calls.
© Peter Andreae COMP102 7:4 Another Java Program Design a Java program to measure reaction time of users responding to true and false "facts". Ask the user about a fact: "Is it true that the BE is a 4 Year degree?" Measure the time they took Print out how much time. Need a class what name? Need a method what name? what parameters? what actions?
© Peter Andreae COMP102 7:5 ReactionTimeMeasurer /** Measures reaction times for responding to true-false statements */ public class ReactionTimeMeasurer { /** Measure and report the time taken to answer a question */ public void measureTime() { // find out the current time and remember it // ask the question and wait for answer // find out (and remember) the current time // print the difference between the two times } } Write the method body in comments first, (to plan the method without worrying about syntax) Work out what information needs to be stored (ie, variables)
© Peter Andreae COMP102 7:6 ReactionTimeMeasurer /** Measures reaction times for responding to a true-false statement */ public class ReactionTimeMeasurer { /** Measure and report the time taken to answer a question */ public void measureTime() { long startTime = System.currentTimeMillis(); String ans =UI.askString("Is it true that the sky is blue?"); long endTime = System.currentTimeMillis(); UI.println("You took " + (endTime - startTime) +" milliseconds"); } } Printing strings with lots of components can be tricky UI.println("You took " + endTime - startTime +" milliseconds"); Bad! Controlling the format can also be tricky.
© Peter Andreae COMP102 7:7 UI.printf Printing with a format string: printf(String format, … other arguments ) UI.printf("You took %d milliseconds to respond\n", (endTime - startTime) ); UI.printf("%4.2f miles is the same as %4.2f km\n", mile, km); Holes all of the form % flags character %smeans print argument as a string %dmeans print argument as an integer %3dmeans print argument as an integer, padded to 3 characters %fmeans print argument as a floating point number %5.2fmeans print argument as floating point, with 2 decimal places, padded to at least 5 characters \nmeans "new line" a string with "holes" values to fill each "hole"
© Peter Andreae COMP102 7:8 Improving ReactionTimeMeasurer (1) /** Measures reaction times for responding to a true-false statement */ public class ReactionTimeMeasurer { /** Measure and report the time taken to answer a question */ public void measureTime() { long startTime = System.currentTimeMillis(); String ans =UI.askString("Is it true that the sky is blue?"); long endTime = System.currentTimeMillis(); UI.printf("You took %d milliseconds \n", (endTime - startTime) ); } } Just asking one question is not enough for an experiment. need to ask a sequence of questions.
© Peter Andreae COMP102 7:9 Good design with methods public void measureTime(){ long time = 0; long startTime = System.currentTimeMillis(); String ans = UI.askString( "Is it true that John Quay is the Prime Minister"); long endTime = System.currentTimeMillis(); UI.printf("You took %d milliseconds \n", (endTime - startTime) ); startTime = System.currentTimeMillis(); ans = UI.askString( "Is it true that 6 x 4 = 23"); endTime = System.currentTimeMillis(); UI.printf("You took %d milliseconds \n", (endTime - startTime) ); startTime = System.currentTimeMillis(); ans = UI.askString( "Is it true that summer is warmer than winter"); endTime = System.currentTimeMillis(); UI.printf("You took %d milliseconds \n", (endTime - startTime) ); startTime = System.currentTimeMillis(); ans = UI.askString( "Is it true that Wellington’s population > 1,000,000"); endTime = System.currentTimeMillis(); time = time + (endTime - startTime); UI.printf("You took %d milliseconds \n", (endTime - startTime) ); } Lots of repetition. But not exact repetition. How can we improve it? Assignment involves breaking programs like this into a method that calls another method
© Peter Andreae COMP102 7:10 Good design with methods Key design principle: Wrap up repeated sections of code into a separate method, Call the method several times: public void measureTime () { this.measureQn( ); } public void measureQn ( … ) { long startTime = System.currentTimeMillis(); String ans =UI.askString("Is it true that ……" ); long endTime = System.currentTimeMillis(); UI.printf("You took %d milliseconds \n", (endTime - startTime) ); } We need to parameterise the method "John Quay is the Prime Minister" ); " 6 x 4 = 23 " ); " summer is warmer than winter " ); " Wellington’s population > 1,000,000 " );
© Peter Andreae COMP102 7:11 Improving ReactionTimeMeasurer (1) public class ReactionTimeMeasurer { public void measureTime() { this.measureQn("John Quay is the Prime Minister"); this.measureQn(“6 x 4 = 23"); this.measureQn(“summer is warmer than Winter"); this.measureQn("Wellington’s population > 1,000,000 "); } public void measureQn(String fact) { long startTime = System.currentTimeMillis(); String ans =UI.askString("Is it true that" + fact); long endTime = System.currentTimeMillis(); UI.printf("You took %d milliseconds \n", (endTime - startTime) ); } this is the object that the current method was called on.
© Peter Andreae COMP102 7:12 "this" and method calls When you call a method on an object, the method "knows" which object it was called on. stored in the "special variable": this If the method needs to call another method from the same class, it generally needs to call it on the same object. public class MyObjects { public void method1(String str1){ … this.method2(45, str1+"-name"); … } public void method2(int num, String n){ … } But, this. is optional! If you leave the object out of a method call, Java will assume you meant this! To be safe: always put the this. in, until you really know what you are doing.
© Peter Andreae COMP102 7:13 What happens if we call the method: RTM1. askQuestions(); public void measureTime(){ this.measureQn("John Quay is the Prime Minister"); this.measureQn("6 x 4 = 23"); this.measureQn(“summer is warmer than Winter"); this.measureQn("Wellington’s population >1,000,000"); The object the method was called on is copied to "this" place Understanding ReactionTimeMeasurer this: RTM- 1
© Peter Andreae COMP102 7:14 public void askQuestions(){ this.measureTime("John Quay is the Prime Minister"); this.measureTime("6 x 4 = 23"); this.measureTime("Summer is warmer than Winter"); this.measureTime("The population of Wellington is over 1,000,000"); Understanding method calls public void measureQn(String fact){ long startTime = System.currentTimeMillis(); String ans = UI.askString("Is it true that " + fact); long endTime = System.currentTimeMillis(); UI.printf("You took %d milliseconds \n", (endTime - startTime) ); } " this: RTM- 1 "John Quay is … "
© Peter Andreae COMP102 7:15 public void measureTime(){ this.measureQn("John Quay is the Prime Minister"); this.measureQn("6 x 4 = 23"); this.measureQn(“summer is warmer than Winter"); this.measureQn("Wellington’s population > 1,000,000"); Understanding ReactionTimeMeasurer this: RTM-1
© Peter Andreae COMP102 7:16 New measureTime worksheet: public void measureTime(String fact){ long startTime = System.currentTimeMillis(); String ans = UI.askString("Is it true that " + fact); long endTime = System.currentTimeMillis(); UI.printf("You took %d milliseconds \n", (endTime - startTime) ); } Each time you call a method, it makes a fresh copy of the worksheet! " 6 x 9 = 54 " Understanding ReactionTimeMeasurer " this: RTM- 1
© Peter Andreae COMP102 7:17 public void MeasureTime(){ this.measureQn("John Quay is the Prime Minister"); this.measureQn("6 x 4 = 23"); this.measureQn(“summer is warmer than Winter"); this.measureQn(" Wellington’s population > 1,000,000"); Understanding ReactionTimeMeasurer this: RTM-1
© Peter Andreae COMP102 7:18 Problem A good experiment would measure the average time over a series of trials Our program measures and reports for each trial. Need to add up all the times, and compute average: problem: MeasureTime needs to add up the times MeasureQn actually measures the time How do we get it back from MeasureQn to MeasureTime?
© Peter Andreae COMP102 7:19 Methods that return values Some methods just have "side effects": UI.println("Hello there!"); UI.printf("%4.2f miles is the same as %4.2f km\n", mile, km); UI.fillRect(100, 100, wd, ht); UI.sleep(1000); Some methods just return a value: long now = System.currentTimeMillis(); double distance = 20 * Math.random(); double ans = Math.pow(3.5, 17.3); Some methods do both: double height = UI.askDouble("How tall are you"); Color col =JColorChooser.showDialog(null, "paintbrush", Color.red);
© Peter Andreae COMP102 7:20 Defining methods to return values Improving ReactionTime: public void measureTime() { long time = this.measureQn("John Quay is the Prime Minister"); time = time + this.measureQn("11 x 13 = 143"); time = time + this.measureQn(“summer is warmer than Winter"); time = time + this.measureQn(" Wellington’s pop > 1,000,000 "); UI.printf("Average time = %d milliseconds\n", (time / 4)); } public void measureQn(String fact) { long startTime = System.currentTimeMillis(); …… } long Specifies the type of value returned. void means "no value returned" measureQn returns a value instead of just printing it out.
© Peter Andreae COMP102 7:21 Syntax: Method Definitions (v3) /** Measure time taken to answer a question*/ public long measureTime( String fact ){ long startTime = System.currentTimeMillis(); : 〈 Comment 〉〈 Header 〉〈 Body 〉 {} public 〈 type 〉 〈 parameters 〉 () 〈 name 〉 〈 type 〉, 〈 name 〉
© Peter Andreae COMP102 7:22 Defining methods to return values If you declare that a method returns a value, then the method body must return one! public long measureQn(String fact) { long startTime = System.currentTimeMillis(); String ans = UI.askString("Is it true that " + fact); long endTime = System.currentTimeMillis(); UI.printf("You took %d milliseconds\n", (endTime - startTime) ); } return (endTime - startTime) ; New kind of statement Means: exit the method and return the value The value must be of the right type
© Peter Andreae COMP102 7:23 What happens if we call the method: RTM-1. askQuestions(); public void measureTime(){ long time = this.measureQn("John Quay is the Prime Minister"); time = time + this.measureQn("6 x 4 = 23"); time = time + this.measureQn(“summer is warmer than Winter"); time = time + this.measureQn(“Wellington’s pop > 1,000,000"); Returning values. this: RTM-1
© Peter Andreae COMP102 7:24 Returning values return value: public long measureQn(String fact){ long startTime = System.currentTimeMillis(); String ans = UI.askString("Is it true that " + fact); long endTime = System.currentTimeMillis(); return (endTime - startTime) ; } "John Quay is … " " this: RTM- 1
© Peter Andreae COMP102 7:25 What happens if we call the method: RTM-1. askQuestions(); public void measureTime(){ long time = this.measureQn("John Quay is the Prime Minister"); time = time + this.measureQn("6 x 4 = 23"); time = time + this.measureQn(“summer is warmer than Winter"); time = time + this.measureQn(" Wellington’s pop > 1,000,000"); Returning values. this: RTM-1