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.
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.
| Method | Signature |
|---|---|
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.
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.
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.
Notice the flow of messages:
MainsendsringUp(cart)toCashier.CashiersendsaddLine(it)toReceiptonce per item.Receiptsendsname()andprice()to eachItem.
No object reaches into another object's fields. The whole computation is a small conversation. Each participant has a small, clear job.
Practice
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 togreet(name).
Expected output:
Hello!
Hello, Ada!
Hola, Bob!
こんにちは, Kenji!
Hello, Eve!
Test your understanding
In the call receipt.addLine(item), which part is the receiver?
addLine
item
receipt
The return value
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)
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