# 3.5 Methods: How to Write Them

Each coding exercise has its own folder. Open its `.java` file and press **Run** to try it. **Run Tests** checks every graded exercise in this lesson at once.

In object-oriented programming, the three main parts of a class are:

- the **instance variables** which hold attributes or values associated with each object,
- the **constructors** whose job is to initialize the instance variables,
- and the **methods** which contain the code for the behaviors of an object and which can use the instance variables defined in the class.

In Unit 1, we used `Turtle` objects and called methods like `forward` which changed the `x` and `y` coordinates (instance variables) of the turtle. We also defined static methods that did not work with objects. In this unit, we will learn how to write our own methods in our own classes.

## Defining and Calling Methods

A **method** is a block of code that performs a specific task. Methods are defined inside a class and can access the instance variables of the class. For example, the print() method below prints the instance variables of the Person class. Methods are usually public.

```java
public class Person
{
    // instance variables
    private String name;
    private String email;

    // Method definition: uses instance variables name and email
    public void print()
    {
        System.out.println("Name: " + name);
        System.out.println("Email: " + email);
    }

    public static void main(String[] args)
    {
        Person p = new Person();
        p.print();  // Method call
    }
}
```

There are three steps to creating and calling a method:

1. **Object of the Class**: Declare an object of your class in the main method or from outside the class.
   ```java
   // Step 1: declare an object in main or from outside the class
   Classname objectName = new Classname();
   ```
2. **Method Call**: whenever you want to use the method, call objectName.methodName();
   ```java
   // Step 2: call the object's method
   objectName.methodName(); //Step 2
   ```
3. **Method Definition**: write the method’s **header** and **body** code like below:
   ```java
   // Step 3: Define the method in the class
   // method header
   public void methodName()
   {
         // method body for the code
   }
   ```

The following flowchart can be used to compare three different ways of calling methods. Class (static) methods are called using the class name. Instance methods which are discussing in this lesson are called using an object of the class. If you are calling the instance method from the main method or from another class, you must first create an object of that class and then call its methods using `object.methodName()`. If you are calling the method from within the same class, you can just call the method using `methodName()` which will refer to the current object.

![Comparing Method Calls to Static and Instance Methods](images/FlowChartCallingMethods.png)

*Comparing Method Calls to Static and Instance Methods*

### Exercise 1

Try the code. Add a print() method in the Person class that prints out all the attributes (name, email, phonenumber) of a person object.

> Open the `01-PersonPrint` folder and edit `Person.java`. Press **Run** to try it; **Run Tests** checks it (1 test). Its test checks your code, not what it prints: “public void print() method”.

## void Methods

A **void method** is a method that does not return a value. It is used when you want to perform an action but do not need to return a value. The method header for a void method looks like this:

```java
public void methodName()
{
    // method body
}
```

The `print` method above is a void method. It does not return a value, but it does print out the name and email of the person. In the sections below, we will learn about setter methods that are also void methods.

## Non-void Methods

A **non-void method** is a method that returns a single value. Its body must have a **return** statement, usually at the end, that returns a variable’s value or an expression. Its header includes the **return type** (the type of the value in the return statement) in place of the keyword `void`. The method header for a non-void method looks like this:

```java
public returnType methodName()
{
    // method body
    return value;
}
```

In Unit 1, we used static non-void methods like `Math.random()` which returned a random number. We also used non-void methods that belonged to Turtle objects like `getXPos()` and `getYPos()` that returned the x and y coordinates of the turtle. The most common non-void methods in Java are methods that start with `get` and return the value of an instance variable. We will learn about these in the next section.

In non-void methods, a return expression compatible with the return type is evaluated, and the value is returned. This is referred to as **return by value**. The `return` keyword is used to return the flow of control to the point where the method or constructor was called. Any code that is sequentially after a return statement will never be executed, so usually non-void methods end with a return statement. Executing a return statement inside a selection or iteration statement will halt the statement and exit the method or constructor.

> Some common errors when writing and using non-void methods are:
>
> - Forgetting a return type like `int` before the method name.
> - Forgetting to use the `return` keyword to return a value at the end of the method.
> - Returning too soon from a method. If you have a return statement in a selection or iteration statement, the method will exit at that point and not execute the rest of the code.
> - Forgetting to do something with the value returned from a method, like assigning it to a variable or printing it out.

## Accessors / Getters

Since the instance variables in a class are usually marked as `private` to the class, if you want code outside the class to be able to access the value of an instance variable, you need to write what is formally called an **accessor methods** but which everyone actually just calls a **getter**. A getter is a `public` method that takes no arguments and returns the value of the `private` instance variable.

If you used a language like App Inventor in an AP CSP class, you may have used setter and getter blocks. In App Inventor, you cannot make your own classes, but you can declare UI objects like Button1, Button2 from the Button class and use their get/set methods for any property like below. (We’ll talk about setters in Java in the next section.)

![App Inventor Set and Get blocks for object Button1](images/AppInvSetGet.png)

*App Inventor Set and Get blocks for object Button1*

You don’t need to write a getter for every instance variable in a class but if you want code outside the class to be able to get the value of one of your instance variables, you’ll need to write a getter that looks like the following.

```java
class ExampleTemplate
{

    // Instance variable declaration
    private typeOfVar varName;

    // Accessor (getter) method template
    public typeOfVar getVarName()
    {
        return varName;
    }
}
```

Notice that the getter’s return type is the same as the type of the instance variable and all the body of the getter does is return the value of the variable using a `return` statement. We’ll talk more about the `return` statement in the next lesson, but for now just notice that it is followed by an expression whose value must be the same type as the return type in the method’s header. In a getter, that will definitely be true as long as the type of the instance variable and the return type of the getter are the same.

Here’s an example of an accessor method called `getName` for the `Student` class which also demonstrates how to call `getName` using a `Student` object:

```java
class Student
{

  //Instance variable name
  private String name;

  /** getName() example
   *  @return name */
  public String getName()
  {
     return name;
  }

  public static void main(String[] args)
  {
     // To call a get method, use objectName.getVarName()
     Student s = new Student();
     System.out.println("Name: " + s.getName() );
  }
```

Note, that getters only return the *value* of the variable.

Try the following code. Note that this exercise has 2 classes! The main method is in a separate **Tester** or **Driver** class. It does not have access to the private instance variables in the other Student class. Note that when you use multiple classes in an IDE, you usually put them in separate files, and you give the files the same name as the public class in them. In code and IDEs, you can put 2 classes in 1 file, as demonstrated here, but only 1 of them can be public and have a main method in it. You can also view the fixed code in the [Java visualizer](http://www.pythontutor.com/visualize.html#code=public%20class%20TesterClass%20%0A%20%20%7B%0A%20%20%20%20%20//%20main%20method%20for%20testing%0A%20%20%20%20%20public%20static%20void%20main%28String%5B%5D%20args%29%0A%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20Student%20s1%20%3D%20new%20Student%28%22Skyler%22,%20%22skyler%40sky.com%22,%20123456%29%3B%0A%20%20%20%20%20%20%20%20System.out.println%28%22Name%3A%22%20%2B%20%20s1.getName%28%29%20%29%3B%0A%20%20%20%20%20%20%20%20System.out.println%28%22Email%3A%22%20%2B%20%20s1.getEmail%28%29%20%29%3B%0A%20%20%20%20%20%20%20%20System.out.println%28%22ID%3A%20%22%20%2B%20s1.getId%28%29%20%29%3B%0A%20%20%20%20%20%7D%0A%20%20%20%7D%0A%20%20%0A%20%20class%20Student%20%0A%20%20%7B%0A%20%20%20%20%20private%20String%20name%3B%0A%20%20%20%20%20private%20String%20email%3B%0A%20%20%20%20%20private%20int%20id%3B%0A%20%20%20%20%20%0A%20%20%20%20%20public%20Student%28String%20initName,%20String%20initEmail,%20int%20initId%29%0A%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20name%20%3D%20initName%3B%0A%20%20%20%20%20%20%20%20email%20%3D%20initEmail%3B%0A%20%20%20%20%20%20%20%20id%20%3D%20initId%3B%0A%20%20%20%20%20%7D%0A%20%20%20%20%20%0A%20%20%20%20%20//%20accessor%20methods%20-%20getters%20%0A%20%20%20%20%20/**%20getName%28%29%20%20%40return%20name%20*/%0A%20%20%20%20%20public%20String%20getName%28%29%20%0A%20%20%20%20%20%7B%20%0A%20%20%20%20%20%20%20%20return%20name%3B%0A%20%20%20%20%20%7D%0A%20%20%20%20%20/**%20getEmail%28%29%20%20%40return%20email%20*/%0A%20%20%20%20%20public%20String%20getEmail%28%29%20%0A%20%20%20%20%20%7B%20%0A%20%20%20%20%20%20%20%20return%20email%3B%0A%20%20%20%20%20%7D%0A%20%20%20%20%20/**%20getName%28%29%20%20%40return%20id%20*/%0A%20%20%20%20%20public%20int%20getId%28%29%20%0A%20%20%20%20%20%7B%20%0A%20%20%20%20%20%20%20%20return%20id%3B%0A%20%20%20%20%20%7D%0A%20%20%7D&cumulative=false&curInstr=26&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=java&rawInputLstJSON=%5B%5D&textReferences=false).

### Exercise 2

Try the code. Note that it has a bug! It tries to access the private instance variable email from outside the class Student. Change the main method in Tester class so that it uses the appropriate public accessor method (get method) to access the email value instead.

> Open the `02-StudentObjExample` folder and edit `TesterClass.java`. Press **Run** to try it; **Run Tests** checks it (2 tests).

## `toString`

While not strictly speaking a getter, another important method that returns a value is the `toString` method. This method is called automatically by Java in a number of situations when it needs to convert an object to a `String`. Most notably the methods `System.out.print` and `System.out.println` use it to convert a object argument into a `String` to be printed and when objects are added to `String`s with `+` and `+=` their `String` representation comes from calling their `toString` method.

Here is the `Student` class again, but this time with a `toString` method. Note that when we call `System.out.println(s1)` it will automatically call the `toString` method to get a `String` representation of the `Student` object. The `toString` method will return a `String` that is then printed out.

### Exercise 3

See the toString() method in action. Add another student object and print it out.

> Open the `03-StudentToString` folder and edit `TesterClass.java`. Press **Run** to try it; **Run Tests** checks it (1 test). Its test checks your code, not what it prints: “Code contains `System.out.println(s2)`”.

## Mutators / Setters

In complement to the accessor/getter methods, if we want to allow code outside the class to *change* the value of an instance variable we have to provide what is formally called a **mutator method** but which everyone actually calls a **setter**. A setter is a void method with a name that starts with `set` and that takes a single argument of the same type as the instance variable to be set. The effect of a setter, as you would probably expect, is to assign the provided value to the instance variable.

Just as you shouldn’t reflexively write a getter for every instance variable, you should think even harder about whether you want to write a setter. Not all instance variables are meant to be manipulated directly by code outside the class.

For example, consider the `Turtle` class. It provides getters `getXPos` and `getYPos` but it does not provide corresponding setters. There are, however, methods that change a `Turtle`’s position like `forward` and `moveTo`. But they do more than just changing the values of instance variables; they also take care of drawing lines on the screen if the pen is down. By not providing setters for those instance variables, the authors of the `Turtle` class can assume the a `Turtle`’s position won’t change other than by going through one of the approved movement methods. In general, you shouldn’t write a setter until you find a real reason to do so.

Here are some examples of how to write a setter for an instance variable:

```java
class ExampleTemplate
{
    // Instance variable declaration
    private typeOfVar varName;

    // Setter method template
    public void setVarName(typeOfVar newValue)
    {
        varName = newValue;
    }
}
```

Here’s an example of the `Student` class with a setter for the `name` variable:

```java
class Student
{
    // Instance variable name
    private String name;

    /**
     * setName sets name to newName
     *
     * @param newName
     */
    public void setName(String newName)
    {
        name = newName;
    }

    public static void main(String[] args)
    {
        // To call a set method, use objectName.setVar(newValue)
        Student s = new Student();
        s.setName("Ayanna");
    }
}
```

Notice the difference between setters and getters in the following figure. Getters return an instance variable’s value and have the same return type as this variable and no parameters. Setters have a void return type and take a new value as a parameter to change the value of the instance variable.

![Comparison of setters and getters](images/get-set-comparison.png)

*Comparison of setters and getters*

Try the `Student` class below which has had some setters added. Notice that there is no `setId` method even though there is a `getId`. This is presumably because in the system this class is part of, while it makes sense for a student to change their name or email, their id should never change.

You will need to fix one error. The `main` method is in a separate class `TesterClass` and does not have access to the `private` instance variables in the `Student` class. Change the `main` method so that it uses a `public` setter to change the value instead.

### Exercise 4

Fix the main method to include a call to the appropriate set method.

> Open the `04-StudentObjExample2` folder and edit `TesterClass.java`. Press **Run** to try it; **Run Tests** checks it (1 test). Its test checks your code, not what it prints: “call to setEmail()”.

> Check your understanding: Consider the class Party which keeps track of the number of people at the party.
>
> ```java
> public class Party
> {
>     // number of people at the party
>     private int numOfPeople;
>
>     /* Missing header of set method */
>     {
>         numOfPeople = people;
>     }
> }
> ```
>
> Which of the following method signatures could replace the missing header for the set method in the code in `04-StudentObjExample2` so that the method will work as intended?
>
> Answer it on CS Awesome: https://runestone.academy/ns/books/published/csawesome2/topic-3-5-methods.html#setSignature

Mutator methods do not have to have a name with “set” in it, although methods that exist just to set a single instance variable usually do. But any method that changes the value of any instance variables is a mutator. Mutator methods are often void methods to make it clear that they are called for their side effects. Some mutators do return a value that provides information about the result of the mutation or the new state of the object. Similarly, mutator methods do not have to take any arguments, but they usually do.

## Parameters

The setter methods above contained parameters. A **parameter** is a variable in a method’s header that is used to pass in data that the method needs to do its job. In a setter, the parameter is the new value that you want to assign to the instance variable. Methods with parameters receive values through those parameters and use those values in accomplishing the method’s task.

An **argument** is a value that is passed into a method when the method is called. It is saved into a parameter variable. The arguments passed to a method must be compatible in number and order with the types identified in the parameter list of the method signature. When calling methods, arguments are passed using call by value. **Call by value** initializes the parameters with copies of the arguments. When an argument is a primitive value, the parameter is initialized with a copy of that value. Changes to the parameter have no effect on the corresponding argument.

![Method signatures with parameters and method calls arguments](images/method-param-arg.png)

*Method signatures with parameters and method calls arguments*

## Methods with Parameters that Return Calculated values

Not all methods that return values are accessor/get methods. Some methods have parameters and return values that are found or calculated in a more complex algorithm. The following method uses a loop to find a letter in a text string given as a parameter. It returns true if the letter is found and false otherwise. Change it to return the count of how many times the letter is found in the text instead.

### Exercise 5

Run the following program which contains a method called findLetter that takes a letter and a text as parameters and uses a loop to see if that letter is in the text and returns true if it is, false otherwise. Set the variables `letter` and `message` to new values in the main method and run it again to try finding a different letter. Then, change the code of the findLetter method to return how many times it finds letter in text, using a new variable called `count`. How would the return type change?

> Open the `05-StringFind` folder and edit `StringFind.java`. Press **Run** to try it; **Run Tests** checks it (5 tests).

## Coding Challenge: Class Pet

![Animal Clinic](images/animalclinic.png)

You’ve been hired to create a software system for the Awesome Animal Clinic! They would like to keep track of their animal patients. Here are some attributes of the pets that they would like to track:

- Name
- Age
- Weight
- Type (dog, cat, lizard, etc.)
- Breed

1. Create a class that keeps track of the attributes above for pet records at the animal clinic. Decide what instance variables are needed and their data types. Make sure you use `int`, `double`, and `String` data types. Make the instance variables `private`.
2. Create a constructor with many parameters to initialize all the instance variables.
3. Create accessor/getter methods for each of the instance variables.
4. Create a `toString` method that returns all the information in a `Pet`.
5. Create mutator/setter methods for each of the instance variables.
6. In the `main` method below, create 2 `Pet` objects with different values and call the constructor, accessor methods, mutator methods, and `toString` methods to test all your code.

### Exercise 6

Create a Pet class that keeps track of the name, age, weight, type of animal, and breed for records at an animal clinic. Create a constructor, getter, setter, and toString() methods. Create 2 Pet objects in the main method and test all your methods.

> Open the `06-challenge-Pet-Class` folder and edit `TesterClass.java`. Press **Run** to try it; **Run Tests** checks it (7 tests).

## Design a Class for your Community

In last lessons, you came up with a class of your own choice relevant to your community.

1. Copy your class with its 3 instance variables, constructor, and its print() and main methods from [lesson 3.4](/lessons/CSA-3.4-Writing-Constructors) into the exercise below.
2. Create accessor (get) methods and mutator (set) methods for each of the instance variables.
3. Create a `toString` method that returns all the information in the instance variables.
4. Write an additional method for your class that takes a parameter. For example, there could be a print method with arguments that indicate how you want to print out the information, e.g. `print(format)` could print the data according to an argument that is “plain” or “table” where the data is printed in a table drawn with dashes and lines (`|`). Or come up with another creative method for your class.
5. Use these methods in the main method to test them. Make sure you use good commenting.

### Exercise 7

Copy your class from [lesson 3.4](/lessons/CSA-3.4-Writing-Constructors). Add get, set, toString, and a method that takes a parameter. For example, there could be a print method with arguments that indicate how you want to print out the information, print(format) where format is “plain” or “table”.

> Open the `07-community-challenge3` folder and edit `Main.java`. Press **Run** to try it; **Run Tests** checks it (8 tests). Name the class, then rename the file to match.

## Summary

- (AP 3.5.A.1) A `void` method does not return a value. Its header contains the keyword `void` before the method name.
- (AP 3.5.A.2) A **non-void method** returns a single value. Its header includes the return type in place of the keyword `void`.
- (AP 3.5.A.3) In non-void methods, a return expression compatible with the return type is evaluated, and the value is returned. This is referred to as **return by value**.
- (AP 3.5.A.4) The `return` keyword is used to return the flow of control to the point where the method or constructor was called. Any code that is sequentially after a return statement will never be executed. Executing a return statement inside a selection or iteration statement will halt the statement and exit the method or constructor.
- (AP 3.5.A.5) An **accessor method** (getter) allows objects of other classes to obtain a copy of the value of instance variables or class variables. An accessor method is a non-void method.
- (AP 3.5.A.6) A **mutator (modifier) method** (setter) is a method that changes the values of the instance variables or class variables. A mutator method is often a void method.
- Comparison of accessor/getters and mutator/setters syntax:

![Get set comparison](images/get-set-comparison.png)

- (AP 3.5.A.7) Methods with parameters receive values through those parameters and use those values in accomplishing the method’s task.
- (AP 3.5.A.8) When an argument is a primitive value, the parameter is initialized with a copy of that value. Changes to the parameter have no effect on the corresponding argument.
- The `toString` method is an overridden method that is included in classes to provide a description of a specific object. It generally includes what values are stored in the instance data of the object. If `System.out.print` or `System.out.println` is passed an object, that object’s `toString` method is called, and the returned `String` is printed. An object’s `toString` method is also used to get the `String` representation when concatenating the object to a `String` with the `+` operator.

> Check your understanding: Drag the definition from the left and drop it on the correct word on the right. — answer it on CS Awesome: https://runestone.academy/ns/books/published/csawesome2/topic-3-5-methods.html#AccessorMutator

## AP Practice

> Check your understanding: Consider the following Party class. The getNumOfPeople method is intended to allow methods in other classes to access a Party object’s numOfPeople instance variable value; however, it does not work as intended. Which of the following best explains why the getNumOfPeople method does NOT work as intended?
>
> ```java
> public class Party
> {
>     private int numOfPeople;
>
>     public Party(int num)
>     {
>         numOfPeople = num;
>     }
>
>     private int getNumOfPeople()
>     {
>         return numOfPeople;
>     }
> }
> ```
>
> Answer it on CS Awesome: https://runestone.academy/ns/books/published/csawesome2/topic-3-5-methods.html#AP-get1

> Check your understanding: Consider the following class definition. The class does not compile.
>
> ```java
> public class Student
> {
>     private int id;
>
>     public getId()
>     {
>         return id;
>     }
>     // Constructor not shown
> }
> ```
>
> The accessor method getId is intended to return the id of a Student object. Which of the following best explains why the class does not compile?
>
> Answer it on CS Awesome: https://runestone.academy/ns/books/published/csawesome2/topic-3-5-methods.html#AP-get2

> Check your understanding: Consider the following class definition.
>
> ```java
> public class Liquid
> {
>     private int currentTemp;
>
>     public Liquid(int temp)
>     {
>         currentTemp = temp;
>     }
>
>     public void resetTemp()
>     {
>         currentTemp = newTemp;
>     }
> }
> ```
>
> Which of the following best identifies the reason the class does not compile?
>
> Answer it on CS Awesome: https://runestone.academy/ns/books/published/csawesome2/topic-3-5-methods.html#AP-mutator1

> Check your understanding: In the `Party` class below, the `addPeople` method is intended to increase the value of the instance variable `numOfPeople` by the value of the parameter `additionalPeople`. The method does not work as intended.
>
> ```java
> public class Party
> {
>     private int numOfPeople;
>
>     public Party(int n)
>     {
>         numOfPeople = n;
>     }
>
>     public int addPeople(int additionalPeople) // Line 10
>     {
>         numOfPeople += additionalPeople; // Line 12
>     }
> }
> ```
>
> Which of the following changes should be made so that the class definition compiles without error and the method `addPeople` works as intended?
>
> Answer it on CS Awesome: https://runestone.academy/ns/books/published/csawesome2/topic-3-5-methods.html#AP-mutator2
