πŸ““5.6: Writing Methods

Table of Contents


πŸ“– This page is a condensed version of CSAwesome Topic 5.6


Writing Methods

Up until this unit, you wrote all your code in the main method, but now we are using lots of methods. Why have multiple methods instead of just one?

Procedural Abstraction allows us to name a block of code as a method and call it whenever we need it, abstracting away the details of how it works.

This serves to organize our code by function and reduce repetition of code. In addition, it helps with debugging and maintenance since changes to that block of code only need to happen in one place!

Here are some of the main reasons to use multiple methods in your programs:

  • Organization and Reducing Complexity: organize your program into small sections of code by function to reduce its complexity. Divide a problem into subproblems to solve it a piece at a time.
  • Reusing Code: avoid repetition of code. Reuse code by putting it in a method and calling it whenever needed.
  • Maintainability and Debugging: smaller methods are easier to debug and understand than searching through a large main method.

How to Write a Method

There are three steps to creating and calling a custom method:

  1. Method Definition: Write the method’s header/signature and body code inside the class that defines the object.
    // Step 1: Define the method in the class
    // Method HEADER/SIGNATURE
    public void methodName() {
     // Method BODY for the repeatable code
    }
    
  2. Object Instance: Declare an object of your class type in the main method or from outside the class.
    // Step 2: Declare an object
    ClassName objectName = new ClassName();
    
  3. Method Call: Whenever you want to use the method, call it on the object by using the dot . operator
    // Step 3: Call the object's method
    objectName.methodName(); 
    
    • πŸ“₯ If the method requires any INPUT to work, provide those values in the parenthesis. These are known as arguments, or actual parameters.
    • πŸ“€ If the method provides any OUTPUT, meaning it has a return value, store it in a variable of the appropriate type (see below for more details on using methods that return values).

🎢 Let’s look at an example with lots of repetition of code and create methods to reduce the repetition of code. You can sing along here: This Old Man Song.

You may have noticed that the chorus is repeated β€œWith a knick knack paddy whack, give a dog a bone. This old man came rolling home.” When you see repeated code, that is a signal for you to make a new method!

For example, here is a chorus() method definition that we could write for the β€œThis Old Man Song”:

public void chorus() {
    System.out.println("With a knick knack paddy whack, give a dog a bone.");
    System.out.println("This old man came rolling home.");
}

Run the tester code in the Java visualizer to see the song This Old Man print out. Can you replace the last two lines in the second verse in the main method with a call the chorus() method instead?

Method Input: Formal Parameters

You may have noticed even more repetition in the song above. What about the lines of each verse? Notice that every word is repeated except the last ones that include a number and a rhyme such as one/thumb and two/shoe.

    System.out.println("This old man, he played one.");
    System.out.println("He played knick knack on my thumb.");
    ...
    System.out.println("This old man, he played two.");
    System.out.println("He played knick knack on my shoe.");

We can make methods even more powerful and more abstract by giving them parameters for data that they need to do their job - think of it like taking INPUT before the process. We can make a method called verse that takes the number and the rhyme to print out any verse!

public void verse(String number, String rhyme) {
       System.out.println("This old man, he played " + number);
       System.out.println("He played knick knack on my " + rhyme);
}

Run the tester code in the Java visualizer to see the song This Old Man print out using the verse and chorus methods. Can you add verse three with the rhyme β€œknee”? Can you add verse four with the rhyme β€œdoor”? How many verses do you know?

πŸ€΅β€β™€οΈπŸ€΅πŸ€΅β€β™‚οΈ When you define your own method, the variables you specify for it in the method header are called formal parameters.

πŸ“£ When you call the method to do its job, you give or pass in arguments or actual parameters to it that are then saved in these local parameter variables.

When a method is called, the right method definition is found by checking the method signature or header at the top of the method definition to match the following:

  1. The method name
  2. The number of arguments
  3. The data types for the arguments
  4. The return type (either void or a data type like int, String, etc.)

For example, imagine we are calling the methods for the This Old Man song:

Song mySong = new Song();
mySong.verse("one", "thumb");
mySong.chorus();
mySong.verse("two", "shoe");
mySong.chorus();

Here’s what that looks like with the 2 method calls above. Notice how the parameter variables get new values with every method call.

image

Java uses Call by Value when it passes arguments to methods. This means that a copy of the value in the argument is saved in the parameter variable. If the parameter variable changes its value inside the method, the original value outside the method is not changed.

If you pass in an argument that holds a reference to an object, like a String or Person or Turtle object, a copy of this reference is passed in and saved in the parameter variable. The formal parameter and the actual parameter (argument) are then aliases, both refering to the same object.

Java was designed this way to avoid copying large objects from method to method. Remember when we discussed reference aliases with Turtle objects who are set equal to one another.

image

Method Output: Return Values

πŸ“€ Methods can also return values of any type back to the calling method, which can be considered OUTPUT. Recall that non-void methods, like we saw when writing getter/accessor methods, return a value of a specific data type.

If a certain method returns a value, the calling method should then do something with this return value, like printing it out or assigning it to a variable (of the same type).

// Printing a value returned from a method call
System.out.print("The student's name is " + student.getName() );
// Storing a return value in a new variable
String studentName = student.getName();

πŸ’» In-Class Activity: Song with Parameters

  1. Go to
  2. Make sure you SIGN IN!
  3. Complete the Programming Challenge: Song with Parameters activity in pairs.

⭐️ Summary

  • Procedural Abstraction (creating methods) reduces the complexity and repetition of code. We can name a block of code as a method and call it whenever we need it, abstracting away the details of how it works.
    • A programmer breaks down a large problem into smaller subproblems by creating methods to solve each individual subproblem.
  • To write methods, write a method definition with a method signature like public void chorus() and a method body in { } and make method calls using an object.methodName() and arguments whenever you need it to do its job.

  • To call an object’s method, you must use the object name and the dot (.) operator followed by the method name, for example object.method();

  • When you call a method, you can give or pass in arguments or actual parameters to it inside the parentheses object.method(arguments). The arguments are saved in local formal parameter variables that are declared in the method header, for example: public void method(type param1, type param2) { ... }.
    • Values provided in the arguments in a method call need to correspond to the order and type of the parameters in the method signature.
    • When an actual parameter is a primitive value, the formal parameter is initialized with a copy of that value. Changes to the formal parameter have no effect on the corresponding actual parameter.
    • When an actual parameter is a reference to an object, the formal parameter is initialized with a copy of that reference, not a copy of the object. The formal parameter and the actual parameter are then aliases, both refering to the same object.
    • When an actual parameter is a reference to an object, the method or constructor could use this reference to alter the state of the original object. However, it is good programming practice to not modify mutable objects that are passed as parameters unless required in the specification.

Acknowledgement

Content on this page is adapted from Runestone Academy - Barb Ericson, Beryl Hoffman, Peter Seibel.