Methods

An operator is a symbol for a function that is built in to the language. They're nice, because they're compact and, once you learn them, readable. However, you can't define your own. A method is a mechanism Java offers you to code your own functions and give them names. And since the number of possible functions is infinite, names are better than symbols anyway. Suppose your game is Rock-Paper-Scissors. What would be the symbol for the function “beats”? You can imagine one, but no one else would know it (remember your readers).

You define a method through a method declaration. You use a method with a method invocation (also called a method call). A method invocation is simpler, so let's start with that.

Method invocation

You invoke a method simply by naming it and providing its arguments between a pair of parentheses. Suppose you had defined a method called beats, and suppose you had defined an enumerated type called Choice (for Rock-Paper-Scissors) like so:

enum Choice { ROCK, PAPER, SCISSORS }

And suppose you had initialized two variables like this:

Choice player1Choice = Choice.PAPER;
Choice player2Choice = Choice.SCISSORS;

then:

beats(player1Choice, player2Choice) false

because Paper does not beat Scissors. (This assumes that you have defined the method so that beats(x, y) evaluates to true if x beats y and false if not.)

When we speak of the result of invoking a method, we don't say “evaluates to,” we say “returns.” So if you were to write the documentation for your beats method, you would write something like “beats(x, y) returns true if x beats y and false if not.”

In the code above, player1Choice and player2Choice are called the method's arguments. Arguments are the values that you send in. Here's the template for invoking a method:

method-name ( argument-list )

If you have a method that takes no arguments, then the argument list is empty. You can imagine a method called “today” that simply returns today's date. This method would require no arguments, so you would invoke it as today().

When invoking a method, the parentheses after the method name are required, whether or not there are any arguments to the method.

Method declarations

The method declaration is where you define the method: you write the code that determines what the method does, you specify what is the method's input data, you specify what type of data the method returns (outputs), and of course you name it. Here's the general form:

return-type method-name ( parameter-list )
{
      [optional statements]
      return return-expr ;
}

return-type, method-name, parameter-list, and return-expr are defined below.

return-type
The type of the value returned by the method.
method-name
The name of the method, following the same rules as other identifiers. Convention dictates that, like a variable, method names begin with a lower-case letter.
parameter-list
A comma-separated list of parameter-type parameter-name declarations.
return-expr
An expression to be evaluated and returned as the result of invoking the method.

Here's the declaration of the beats method:

boolean beats ( Choice player1Choice, Choice player2Choice )
{
  return player1Choice == Choice.ROCK && player2Choice == Choice.SCISSORS
         || player1Choice == Choice.PAPER && player2Choice == Choice.ROCK
         || player1Choice == Choice.SCISSORS && player2Choice == Choice.PAPER;
}

There are different ways to implement this method; this way happens to not require anything we haven't learned already. You could read the code this way:

There are three possible ways for player1Choice to beat player2Choice, all joined together with || (OR) operators so that if any of them are true, the method returns true. Return true if player1Choice is Rock and player2Choice is Scissors, or if player1Choice is Paper and player2Choice is Rock, or if player1Choice is Scissors and player2Choice is Paper. If none of those cases is true, return false.

You can see from this example that it is no problem letting an expression spread over multiple lines. We did it in this case to make the code easier to read. Strictly speaking, how you indent your lines of code is ultimately up to you, because the compiler doesn't care. As with identifiers, there are some pretty firm conventions, but more on this later.

Maybe for your Rock-Paper-Scissors game, a method that determines if there is a tie would be useful. Here is method that does that:

boolean tie ( Choice player1Choice, Choice player2Choice )
{
    return !beats(player1Choice, player2Choice) 
           && !beats(player2Choice, player1Choice);
}

It's a tie if player1Choice does not beat player2Choice and player2Choice does not beat player1Choice. The operator-precedence table tells us that because the ! (NOT) operator has higher precedence than the && (AND) operator, we don't need parentheses to control the order of evaluation.

You may have realized that there is a simpler way:

boolean tie ( Choice player1Choice, Choice player2Choice )
{
    return player1Choice == player2Choice;
}