Dataslope logoDataslope

Methods and Messages

How objects communicate, what method overloading means, and why we treat a method call as "sending a message"

We have used the word message loosely so far. This page nails it down. In an object-oriented program, calling dog.bark() is more than just "running a function" — it is asking the dog to bark, and letting the dog decide how. That framing changes how you design software.

A method call is a message sent to a receiver

Every Java method call on an object follows the same shape:

receiver . message ( arguments )
  • The receiver is the object the method is called on.
  • The message is the method name.
  • The arguments are the extra information you give the receiver to do its job.

The receiver decides how to respond. The caller doesn't need to know — and shouldn't care — what the receiver does internally to fulfill the request.

This is not just terminology. Thinking of method calls as messages between objects is what lets you design systems whose pieces can be swapped, refactored, or replaced — because each receiver is free to implement the message in its own way.

Code Block
Java 8 (Update 492)

The caller in main does not know that Lamp clamps the brightness to [0, 1]. The caller only knows: "I sent the message setBrightness(2.0), and afterwards describe() says 100%." The lamp owns its response.

The signature of a method

A method's signature is its name plus the types (and order) of its parameters. The return type is not part of the signature.

MethodSignature
void turnOn()turnOn()
void setBrightness(double b)setBrightness(double)
String describe()describe()

Two methods in the same class may share a name only if their signatures differ — different number of parameters, different parameter types, or different parameter order. This is method overloading.

Code Block
Java 8 (Update 492)

Overloading should be used sparingly. If two overloads do different things, give them different names. If they do the same thing for different argument shapes (the Printer above is borderline), it can be cleaner.

Commands vs. queries

A small, classic distinction that helps you design methods:

  • A command changes the object's state. It usually returns void. Example: lamp.turnOn(), account.deposit(50).
  • A query answers a question and does not change the object's state. Example: lamp.brightness(), account.balance().

A method that does both — modifies state and returns a meaningful value — is sometimes useful (think boolean spend(int) from the Wallet exercise) but is the most error-prone shape. Keep it rare and keep the name honest (tryWithdraw, popOrNull).

Methods can call other methods on the same object

A method body can use this.someMethod() (or just someMethod()) to delegate to another method on the same object. This is how you build complex behavior out of small, well-named parts.

Code Block
Java 8 (Update 492)

summary() doesn't recompute the elapsed time itself — it sends the message elapsedNs() to this. If the formula ever changes, you change it in one place.

Methods can call methods on other objects

This is where OOP really comes alive: an object's method can fulfill its responsibility by sending messages to other objects. The example below — three classes, one diagram — is the pattern you will use thousands of times.

Code Block
Java 8 (Update 492)

Notice the flow of messages:

  1. Main sends ringUp(cart) to Cashier.
  2. Cashier sends addLine(it) to Receipt once per item.
  3. Receipt sends name() and price() to each Item.

No object reaches into another object's fields. The whole computation is a small conversation. Each participant has a small, clear job.

Practice

Challenge
Java 8 (Update 492)
Greeter overloads

Implement a Greeter class with three overloaded methods called greet:

  • greet() returns "Hello!"
  • greet(String name) returns "Hello, " + name + "!"
  • greet(String name, String lang) returns a language-specific greeting:
  • For lang.equals("en") returns "Hello, " + name + "!"
  • For lang.equals("es") returns "Hola, " + name + "!"
  • For lang.equals("ja") returns "こんにちは, " + name + "!"
  • For any other value of lang, fall back to greet(name).

Expected output:

Hello!
Hello, Ada!
Hola, Bob!
こんにちは, Kenji!
Hello, Eve!

Test your understanding

QuestionSelect one

In the call receipt.addLine(item), which part is the receiver?

addLine

item

receipt

The return value

QuestionSelect one

Which pair of methods is a valid example of method overloading?

int compute() and double compute()

void print(String s) and void print(int n)

public void run() and private void run()

void log(String s) and void log(String s)

QuestionSelect one

In OOP, what is the practical advantage of thinking of method calls as messages sent to a receiver rather than just "function calls"?

The JVM dispatches messages faster than function calls

It makes the program use less memory

It reminds you that the receiver decides how to respond, so you focus on what each object should do rather than how callers should reach into it

It removes the need for return values

On this page