Calling Predefined Methods Thus far we have seen several constructs that allow us to make decisions and repeat code. While this gives us a fair amount of power to make programs with, we have yet to tap into perhaps the most powerful tool provided in Java and virtually all other programming languages: methods. (In other languages these are often known as functions or procedures.) The idea is this: so many program contain a task that needs to be repeated several times. Rather than type in that code specifically each time we need it, Java allows up to define methods that act just like little subprograms. This way, we write the method only once, and then are allowed to call it whenever we want. In a more general sense, a method can solve some sort of general problem, given some input. A simple example of this is a method that takes the square root of the number passed to it as input. You can use this method whether your taking the square root of 25, 36 or any variable expression. You simply must TELL the method what you want to take the square root of... Before we discuss how to write our own methods, we will talk about how to USE methods that are already written. One of the advantages of programming in Java is that there are a plethora of pre-written methods (in classes) that you can use. You do not need to understand how they work; you just need to understand what they do. (For example, you’d need to know that a method took the square root of the number “passed to it” to use the method correctly, but you wouldn’t need to know whether or not Newton’s approximation method was being used to compute the square root.) In order to use a method, you must first understand the prototype for the method. Here is an example of a method prototype: double sqrt(double x); In general, a method prototype would look like the following: <return type> <method name>(<type of first parameter>, <type of second parameter>,...) A method can have an arbitrarily large number of parameters. However, most methods usually do not have more than 4 or 5 parameters. Each parameter is an “input” to the method. The method is only allowed to have one answer or “output”. Only the type of the output is specified in the method prototype. In our example, our method takes in a single parameter that is a double and returns to us a value that is also a double. To use this method, you must place the method call where you would place an expression of the type double. You must use the name of the method, (along with the class that it comes from), and for each parameter listed you must pass in an expression that matches the type of that parameter. So, the following would be a valid call to the sqrt method: System.out.println(“The square root of 34.5 is “ + Math.sqrt(34.5)); Essentially, when the computer executes the instruction above, the first thing it notices is that it doesn’t know what Math.sqrt(34) is equal to. In particular, the computer recognizes from the syntax that this is a method call and it needs to go and execute all of the lines of code in the method. To decide whether the method call is valid or not(this is actually done in the compilation process not when the computer is executing the code), the computer checks to see if it can find the definition for the sqrt method in the Math class, and if so, if the number of parameters, as well as their types match what is given in the prototype. In this case, the parameter 34.5 is a double and it’s the only parameter, so the method call is valid. Once this is determined, the method is executed. For our purposes all we have to know is that the method will return a double as the “answer” to its computation. That answer is what the entire expression above evaluates to. Thus in this case, the number (which is 5 point something) which gets returned by the method is concatenated with the string “The square root of 34.5 is “ and printed out. Before I show an useful example using method calls, I will introduce a second method in the math class: double pow(double x, double y) This method calculates the value of x raised to the y power. Clearly, it will not work if you pass it mathematically inappropriate values. The full documentation of the math class would describe what parameters are valid to pass to the method. Here is a simple example of a segment of code that calculates the distance between to Cartesian points. In this example, pay attention to how each method call simply acts as an expression of its return type. System.out.println(“Enter the x and y coordinates of the first point.”); int x1 = Integer.parseInt(stdin.readLine()); int y1 = Integer.parseInt(stdin.readLine()); System.out.println(“Enter the x and y coordinates of the second point.”); int x2 = Integer.parseInt(stdin.readLine()); int y2 = Integer.parseInt(stdin.readLine()); double distance = Math.sqrt(Math.pow(x2 – x1, 2) + Math.pow(y2 – y1, 2)); When the computer is evaluating the last line of code above, it realizes that it does not know the value to the parameter of Math.sqrt. It must evaluate both method calls inside the parentheses to find the correct value to pass to the Math.sqrt method. So, it first calls Math.pow with the parameters x2-x1 and 2. Notice that the order of the parameters matters. (If we passed the parameters into the method in the opposite order, then the method would calculate 2x2-x1, which is not what we want to calculate.) Each parameter gets evaluated, and then these values get passed to the method when its called. The method then returns the answer. In this situation, the answers that get returned from the two Math.pow calls get added together and passed to the Math.sqrt method as a parameter. This finally returns a single double value which then gets stored into the variable distance. You can think of a method as a black box. You do not know what’s inside the black box, but the black box performs a particular task. You must give it the requested inputs(the parameters), and it will produce an output. You may use that output in any way that you need to. The trick with methods is figuring out which one would be beneficial to use for a particular program and what parameters to pass to the method. When we start writing our own methods we will talk about both formal and actual parameters. For now, all you need to know is that the parameters you PASS to a method are actual parameters. There are a few important issues that have yet to be mentioned. First of all, all of java’s prewritten methods lie in classes. One or more classes make up a package. Anytime we want to use a prewritten method, we must import the package (or class) that the method we are using belongs to. For the previous example we would need to import the java.lang.Math class as follows: import java.lang.Math; Next there are two types of methods: static and non-static methods. For now, we will only deal with static methods. Once we introduce HOW to define our own class, we will introduce non-static methods. When we call a static method, if we are NOT in the class that the method is in (this will always be the case when we use Java’s prewritten methods), we must call it by first naming the class, then using the dot operator, followed by the name of the method, as was illustrated in the example above. Here is an example of a program using the same two prewritten methods: import java.io.*; import java.lang.Math; class Quadratic { public static void main(String argv[]) throws IOException { BufferedReader stdin = new BufferedReader (new InputStreamReader(System.in)); double a, b, c; // Prints out labels for each column of mult. table System.out.println(“Enter the coefficients of your quadratic.”); System.out.println(“Place one coefficient per line.”); a = (Double.valueOf(stdin.readLine())).doubleValue(); b = (Double.valueOf(stdin.readLine())).doubleValue(); c = (Double.valueOf(stdin.readLine())).doubleValue(); if (a == 0) System.out.println(“Sorry that is not a valid quadratic.”); else { double disc = Math.sqrt(math.pow(b,2) – 4*a*c); double root1 = (-b + disc)/(2*a); double root2 = (-b – disc)/(2*a); System.out.println(“The first root is “ + root1); System.out.println(“The second root is “ + root2); } } } Once again, what makes this program work is that we pass the appropriate parameters to each method call. As you can see with the types of methods we have seen so far that return a value(some methods don’t – we will talk about those later), we usually do one of the following with our method call: 1) Print out the value the method returns. 2) Use the value the method returns in an arithmetic expression. 3) Set some variable equal to the value the method returns. 4) Pass the value the method returns to another method as a parameter. In essence, we need to somehow use the information a method call is returning to us. Each of the ways listed above utilizes this information.