Section 3.5. Creating Methods

[Page 50 (continued)]

3.5. Creating Methods

We had to send many messages to our Turtle object just to draw two squares. Do you notice any similarities in how we draw the squares? Each time we draw a square we turn right and go forward by 30 steps for a total of four times. It would be nice to name the list of steps for drawing a square and then just do the list of steps when a turtle is asked to draw a square. We do this by creating a method that knows how to draw a square. Methods are named blocks of commands that are defined inside a class definition. Once we have defined a method and successfully compiled the class definition, the objects of the class will respond to a message with the same name and parameters as the new method. So if we want Turtle objects to understand the message drawSquare(), we define a method drawSquare().

[Page 51]

Computer Science Idea: Messages Map to Methods

When we send an object a message, it must map to a method that objects of that class understand. If objects of the class don't understand the message, you will get an error when you compile. Be sure that the parameter list is correct, because if it isn't you will get an error that says such a method does not exist. Make sure that you compile a new method before you try and use it.

You have seen how to declare variables in Java:

type name; or type name = expression;.

To declare a method in Java use:

visibility type methodName(parameterList)

The structure of how you declare a method is referred to as the syntaxthe words and characters that have to be there for Java to understand what's going on, and the order of those things.

A method declaration has a visibility (usually the keyword public), the type of the thing being returned from the method, the method name, and the parameter list in parentheses. This is usually followed by a block of statements which is an open curly brace followed by a series of statements followed by a close curly brace. The statements in the block will be executed when the method is invoked.

Common Bug: Curly Braces Come in Pairs

Each open curly brace in your Java code must have a matching close curly brace. You should indent code inside of a pair of curly braces. Indentation doesn't matter to the compiler but makes your code easier to read and understand. Be careful not to mix up curly braces and parentheses.

To declare a method that will draw a square we can use:

public void drawSquare() {   // statements to execute when the method is executed }

The visibility in this method declaration is public. Visibility means who can invoke the method (ask for the method to be executed). The keyword public means that this method can be invoked by any code in any class definition. If the keyword private is used then the method can only be accessed from inside the class definition. You can think of this as a security feature. If you keep your journal on the Web (a blog), then it is open and anyone can read it. If you keep it hidden in your room then it is private and hopefully only you can read it.

[Page 52]

The return type in this method declaration is void. The return type is required and is given before the method name. If you leave off a return type you will get a compiler error. If your method returns a value the return type must match the type of the value returned. Remember that types can be any of the primitive types (char, byte, int, short, long, float, double, or boolean) or a class name. Methods that don't return any value use the Java keyword void for the return type in the method declaration.

The method name in this declaration is drawSquare. By convention method names start with a lowercase letter and the first letter of each additional word is uppercase: drawSquare. Another example method name is turnRight.

A method must have parentheses following the method name. If any parameters are passed to the method then they will be declared inside the parentheses separated by commas. To declare a parameter, you must give a type and name. The type can be any primitive type or class name. The name can be used by the code in the body of the method to refer to the passed value.

We create a collection of statements by defining a block. A block is code between an open curly brace '{'and a close curly brace'}'. The block of commands that follow a method declaration are the ones associated with the name of the method (function) and are the ones that will be executed when the method is invoked.

Most real programs that do useful things require the definition of more than one method (function). Imagine that in the definitions pane you have several method declarations. How do you think Java will figure out that one method has ended and a new one begun? Java needs some way of figuring out where the method body ends: Which statements are part of this method and which are part of the next? Java uses curly braces to do this. All statements between the open curly brace and close curly brace are part of the method body.

Debugging Tip: Proper Method Declarations

All method declarations must be inside a class definition which means that they are defined inside the open '{'and close'}' curly braces that enclose the body of the class definition. If you put a method declaration after the end of the class definition you will get "Error: 'class' or 'interface' expected''. Methods can not be defined inside of other methods. If you accidently do this you will get "Error: illegal start of expression'' at the beginning of the inner method declaration. Statements in a method end in a semicolon (this is not optional in the definitions pane). If you forget to put the semicolon at the end of a statement, you will get "Error: ';' expected''. All compiler errors will highlight the line of code that caused the error. If you don't see the error on that line of code, check the preceding line. You can double-click on an error in the "Compiler Output'' area and it will place the cursor at that line of code and highlight it.

We can now define our first program (method)! Open by clicking on the Open button near the top of the window and using the file chooser to pick "". Type the following code into the definitions pane of DrJava before the last closing curly brace '}' (which ends the class definition). When you're done, save the file and click the Compile All button near the top of the window (Figure 3.8).

[Page 53]

Figure 3.8. Defining and executing drawSquare().

Debugging Tip: Compile All

The COMPILE ALL button will compile all open files. If you have an empty file open named (UNTITLED) go ahead and close it. DrJava creates this for you so that you can start writing a new class definition. But we won't do that right away. Select the name of the file in the Files Pane and press the CLOSE button to close a file.

Program 2. Draw a Square
(This item is displayed on pages 53 - 54 in the print version)

public void drawSquare() {   this.turnRight();   this.forward(30);   this.turnRight();   this.forward(30);   this.turnRight(); 
[Page 54]
this.forward(30); this.turnRight(); this.forward(30); }

Making it Work Tip: Copying and Pasting

Text can be copied and pasted between the interactions pane and definitions pane. To copy text select it and click COPY (in the EDIT menu), then click in the definitions pane and click on PASTE (also in the EDIT menu). You can also use keyboard shortcuts for copy (Control-c) and paste (Control-v). This means to hold the "Ctrl" key and then press the "c" key to copy and hold the "Ctrl" key and the 'v' key to paste. You can copy entire methods in the definitions pane by selecting the text in the method and then copying and pasting it. You can select a method name in the definitions pane and paste it in the interactions pane to send a message asking for that method to be executed. You can also try things out in the interactions pane and later save them in a method in the definitions pane.

Notice that we changed turtle1.turnRight(); to this.turnRight();. The variable turtle1 isn't defined inside the method drawSquare(). Variables names are known in a context (area that they apply). This is also known as the scope of a variable. The variables that we define in the interactions pane are only known in the interactions pane, they aren't known inside methods. We need some other way to reference the object that we want to turn. Object methods are implicitly passed a reference to the object the method was invoked on. You can refer to that current object using the keyword this.

Compiling a Java class definition "" will produce a "Turtle.class" file. Compiling translates the Java source code which is in a format that humans understand into a format that computers understand. One of the advantages to Java is that the ".class" files aren't specific to any particular type of computer. They can be understood by any computer that has a Java run-time environment. So you can create your Java source code on a Window's based computer and run the compiled code on an Apple computer.

Making it Work Tip: Try Every Program!

To really understand what's going on, type in, compile, and execute every program (method) in the book. EVERY one. None are long, and the practice will go a long way toward convincing you that the programs work, developing your programming skill, and helping you understand why they work.

This code creates a method with the name drawSquare that takes no parameters and whenever the method is executed it will execute the statements inside of the open and close curly braces. It is a public method. It doesn't return anything so it uses the keyword void to indicate this. This method must be called on an object of the Turtle class. The this is a keyword that refers to the object this method was invoked on. Since this method is defined in the Turtle class the keyword this will refer to a Turtle object.

[Page 55]

Once the method has successfully compiled you can ask for it to be executed by sending a message to a Turtle object with the same name and parameter list as the method. Click on the INTERACTIONS tab in the interactions pane (near the bottom of the window). This method doesn't take any parameters, so just finish with the open and close parentheses and the semicolon. When you compile the interactions pane will be reset, meaning that all the variables we have defined in the interactions pane will no longer be understood. We will need to create a World and Turtle object again.

> World world1 = new World(); > Turtle turtle1 = new Turtle(world1); > turtle1.drawSquare();

When you invoke the method drawSquare() on the Turtle object referenced by the variable turtle1, the Java Virtual Machine has to find the method to execute. Methods are defined inside of a class definition so we defined drawSquare inside of the class Turtle by editing the file Next we compiled the source file which created a Turtle.class file which contained the code for the Turtle class in byte codes for the Java virtual machine.

The first time you use a class the Java Virtual Machine loads the compiled class definition (the Turtle.class file) and creates an object that contains all the information about the class including the code for the methods. Every object has a reference to the object that defines its class as shown by Figure 3.9. The object that defines a class is an object of a class named Class. You can get the Class object using the method getClass().

> System.out.println(world1.getClass()); class World > System.out.println(turtle1.getClass()); class Turtle

Figure 3.9. An object stores data for that object and has a reference to the class that created it.
(This item is displayed on page 56 in the print version)

The Java Virtual Machine will check for a method with the same name and parameter list in the object that defines the class (an object of the class Class) and if it is found it will execute that method. This means that the statements in the body of the method will be executed starting with the first statement. The object that the method was invoked on is implicitly passed to the method as well and can be referred to using the keyword this.

What if we want to draw a larger or smaller square? We could change each of the this.forward(30); lines to the new width and height and then compile. But, it would be easier to declare a variable in the method that would represent the width of the square and then use that variable name as the amount to go forward by like this: this.forward(width);. Then if we want to change the size of the square we only have to change 1 line. You can declare a variable anywhere in the body of a method but you must declare it before you use it. The name will be known and the value substituted for each occurrence of the name in the rest of the method. But the name will only be known inside the method it is declared in.

[Page 56]

We can't have two methods with the same name and the same parameter list so we need a new name for this method. We simply named it drawSquare2 to show that it is the second version. We can copy the first method and paste it and rename it and then change it to declare and use the width variable.

Program 3. Draw Square Using a Variable for Width

public void drawSquare2() {     int width = 30;     this.turnRight();     this.forward(width);     this.turnRight();     this.forward(width);     this.turnRight();     this.forward(width);     this.turnRight();     this.forward(width); }

Compile and run this method and check that you get the same results as with drawSquare().

> World world = new World(); > Turtle turtle1 = new Turtle(world); > turtle1.drawSquare2();

[Page 57]

3.5.1. Methods that Take Input

This is a bit better than the first version and a bit easier to change. But, you still have to recompile after you change the width to draw a larger or smaller square. Wouldn't it be nice if there was a way to tell the method what size you want when you ask for the method to be executed by sending a message that matches the method? Well you can! That is what the parameter list is for.

We can make the width of the square a parameter. Remember that if a method takes a parameter you must list the type and name for the parameter in the parameter list. What type should we use for width? Well, in the second version we used int because the turtle only takes whole steps not fractional ones so let's use that. What should we call this method? We could call it drawSquare3(int width) but someone may think this means it draws a square with a width of 3. We could call it drawSquareWithPassedWidth(int width) but that is rather long and you can tell it takes a passed width by looking at the parameter list. How about if we just call it drawSquare(int width)? You may think that isn't allowed since we have a method drawSquare(), but that method doesn't take any parameters and our new method does. Java allows you to use the same method name as another method as long as the parameter list is different. This is called method overloading.

Program 4. Draw Square with Width as a Parameter

/**  * Method to draw a square with a width and height  * of some passed amount.  * @param width the width and height to use  */ public void drawSquare(int width) {   this.turnRight();   this.forward(width);   this.turnRight();   this.forward(width);   this.turnRight();   this.forward(width);   this.turnRight();   this.forward(width); }

Type in the new method declaration and compile. Let's try this new method out.

> World world1 = new World(); > Turtle turtle1 = new Turtle(world1); > turtle1.drawSquare(200);

When you execute turtle1.drawSquare(200); you are asking the object referred to by the variable named turtle1 to execute a method named drawSquare that takes an integer parameter. The method drawSquare will use 200 for the parameter width everywhere it appears in the method drawSquare, with the result shown in Figure 3.10. The parameter name width is known throughout the body of the method. This is very similar to drawSquare2() but has the advantage that we don't need to change the method and recompile to use a different width.

[Page 58]

Figure 3.10. Showing the result of sending the width as a parameter to drawSquare.

An important reason for using parameters is to make a method more general. Consider method drawSquare(int width). That method handles the general case of drawing a square. We call that kind of generalization abstraction. Abstraction leads to general solutions that work in lots of situations.

Making it Work Tip: Use Names that Make Sense

We called the first method drawSquare() and the second drawSquare2().Does it matter? Absolutely not! Well, not to the computer, at any rate. The computer doesn't care what names you usethey're entirely for your benefit. Pick names that (a) are meaningful to you (so that you can read and understand your program), (b) are meaningful to others (so that others can read and understand it), and (c) are easy to type. Long names, like,


are meaningful, easy-to-read, but are a pain to type.

Does this mean that you can use "orange" as a method name? Yes, you can, but it may be confusing even for you, and especially confusing for others. It helps to use method names that indicate what the method does.

Defining a method that takes input is very easy. It continues to be a matter of substitution and evaluation. We'll put a type and name inside those parentheses after the method name. The names given inside the parentheses are called the parameters or input variables.

When you evaluate the method, by specifying its name with input values (also called the arguments) inside parentheses, such as turtle1.drawSquare(20); or new Turtle(20,30,world1), each parameter variable is set to a copy of the argument value. This is called pass by value. All arguments in Java are passed by making a copy of their value. Does this mean that we make a copy of the World object when we pass it as a parameter? No, we just make a copy of the object reference which means we make another reference to that World object.

[Page 59]

Introduction to Computing & Programming Algebra in Java(c) A Multimedia Approach
Introduction to Computing & Programming Algebra in Java(c) A Multimedia Approach
Year: 2007
Pages: 191 © 2008-2017.
If you may any questions please contact us: