Java Method Overloading Tutorial with Real-Time Project Example
Last Updated on: 12th Nov 2025 13:51:04 PM
Welcome to this beginner-friendly tutorial on Method Overloading in Java! Method Overloading is a powerful compile-time polymorphism feature that allows you to define multiple methods with the same name but different parameters in the same class.
This tutorial uses a real-world project-based example — an Online Food Delivery System — to show how method overloading is used in real software development.
What is Method Overloading?
Method Overloading occurs when a class has multiple methods with the same name but different parameter lists (different in number, type, or order of parameters).
-
Decided at compile time (Compile-time Polymorphism).
-
Improves code readability and reusability.
-
Return type does NOT matter for overloading.
Rules for Method Overloading
-
Same method name
-
Different parameters:
-
Different number of parameters
-
Different data types of parameters
-
Different order of parameters
-
-
Return type can be same or different (doesn't affect overloading)
Example of Method Overloading
When you use an ATM machine, you can withdraw money in multiple ways:
-
By entering amount only.
-
By entering amount + account type (e.g., savings or current).
-
By entering amount + account type + PIN (for additional security).
All these actions perform the same task — withdrawing money,
but the inputs differ, which is exactly what Method Overloading is.
class ATM {
// 1️⃣ Withdraw money by amount only
void withdraw(int amount) {
System.out.println("Withdrawing ₹" + amount + " from default account.");
}
// 2️⃣ Withdraw money with account type
void withdraw(int amount, String accountType) {
System.out.println("Withdrawing ₹" + amount + " from " + accountType + " account.");
}
// 3️⃣ Withdraw money with account type and PIN
void withdraw(int amount, String accountType, int pin) {
System.out.println("Verifying PIN...");
System.out.println("Withdrawing ₹" + amount + " from " + accountType + " account using PIN " + pin + ".");
}
}
public class ATMExample {
public static void main(String[] args) {
ATM atm = new ATM();
// Calling overloaded methods
atm.withdraw(2000);
atm.withdraw(5000, "Savings");
atm.withdraw(10000, "Current", 1234);
}
}
Output
Withdrawing ₹2000 from default account.
Withdrawing ₹5000 from Savings account.
Verifying PIN...
Withdrawing ₹10000 from Current account using PIN 1234.
Explanation
-
The method
withdraw()is used three times with different parameter lists. -
The compiler decides which version to call based on the arguments provided.
-
All methods perform the same logical task — withdraw money — but handle it differently depending on input.
This demonstrates compile-time polymorphism through method overloading.
How It Works
-
The compiler decides which
add()method to call based on parameters. -
This decision happens at compile time, hence called compile-time polymorphism.
Ways to Overload a Method
You can overload a method by changing:
-
Number of Parameters
void show(int a)
void show(int a, int b)
- Type of Parameters
void show(int a)
void show(double a)
- Order of Parameters
void show(int a, double b)
void show(double a, int b)
What You Cannot Do
❌ You cannot overload methods just by changing the return type:
int add(int a, int b) { return a + b; }
double add(int a, int b) { return a + b; } // ❌ Error: Same parameter list
Real-World Understanding
| Action | Method Called | Description |
|---|---|---|
| Withdraw ₹2000 | withdraw(int) |
Basic withdrawal |
| Withdraw ₹5000 from Savings | withdraw(int, String) |
Chooses account |
| Withdraw ₹10000 using PIN | withdraw(int, String, int) |
Adds security layer |
Real-Time Project: Online Food Delivery System
Let’s build a Food Ordering App where users can:
-
Place orders with different details.
-
Apply discounts based on order type.
-
Generate receipts.
We’ll use method overloading in the OrderProcessor class to handle different ways of placing an order.
Step 1: FoodItem Class
// FoodItem.java
public class FoodItem {
private String name;
private double price;
private String category;
public FoodItem(String name, double price, String category) {
this.name = name;
this.price = price;
this.category = category;
}
// Getters
public String getName() { return name; }
public double getPrice() { return price; }
public String getCategory() { return category; }
@Override
public String toString() {
return name + " (₹" + price + ") - " + category;
}
}
Step 2: OrderProcessor Class with Overloaded Methods
// OrderProcessor.java
import java.util.ArrayList;
import java.util.List;
public class OrderProcessor {
private List<FoodItem> cart;
private double discount = 0.0;
public OrderProcessor() {
this.cart = new ArrayList<>();
}
// 1. Overloaded Method: Place order with just item name and price
public void placeOrder(String itemName, double price) {
FoodItem item = new FoodItem(itemName, price, "General");
cart.add(item);
System.out.println("Added: " + item);
}
// 2. Overloaded: Place order with name, price, and category
public void placeOrder(String itemName, double price, String category) {
FoodItem item = new FoodItem(itemName, price, category);
cart.add(item);
System.out.println("Added: " + item);
}
// 3. Overloaded: Place order with quantity
public void placeOrder(String itemName, double price, int quantity) {
for (int i = 0; i < quantity; i++) {
placeOrder(itemName, price); // Reuse simpler method
}
System.out.println("Added " + quantity + " x " + itemName);
}
// 4. Overloaded: Place order with item + discount
public void placeOrder(String itemName, double price, double discountPercent) {
double discountedPrice = price - (price * discountPercent / 100);
FoodItem item = new FoodItem(itemName, discountedPrice, "Discounted");
cart.add(item);
System.out.println("Added (with " + discountPercent + "% off): " + itemName + " @ ₹" + discountedPrice);
}
// 5. Overloaded: Place order with full details
public void placeOrder(String itemName, double price, String category, int quantity, boolean isExpress) {
double totalPrice = price * quantity;
if (isExpress) {
totalPrice += 50; // Express delivery fee
}
for (int i = 0; i < quantity; i++) {
FoodItem item = new FoodItem(itemName, price, category + (isExpress ? " (Express)" : ""));
cart.add(item);
}
System.out.println("Added " + quantity + " x " + itemName + " | Total: ₹" + totalPrice);
}
// Generate receipt
public void generateReceipt() {
System.out.println("\n" + "=".repeat(40));
System.out.println(" RECEIPT");
System.out.println("=".repeat(40));
double total = 0;
for (FoodItem item : cart) {
System.out.println(item);
total += item.getPrice();
}
System.out.println("-".repeat(40));
System.out.println("Total: ₹" + total);
System.out.println("=".repeat(40) + "\n");
}
public int getCartSize() { return cart.size(); }
}
Step 3: Main App – FoodDeliveryApp
// FoodDeliveryApp.java
public class FoodDeliveryApp {
public static void main(String[] args) {
OrderProcessor order = new OrderProcessor();
System.out.println("Placing Orders Using Method Overloading:\n");
// 1. Simple order
order.placeOrder("Margherita Pizza", 399);
// 2. With category
order.placeOrder("Cold Coffee", 150, "Beverages");
// 3. With quantity
order.placeOrder("Garlic Bread", 129, 2);
// 4. With discount
order.placeOrder("Pasta", 450, 20); // 20% off
// 5. Full details with express
order.placeOrder("Biryani", 320, "Main Course", 1, true);
// Generate final receipt
order.generateReceipt();
System.out.println("Total items in cart: " + order.getCartSize());
}
}
Output
Placing Orders Using Method Overloading:
Added: Margherita Pizza (₹399.0) - General
Added: Cold Coffee (₹150.0) - Beverages
Added 2 x Garlic Bread
Added (with 20.0% off): Pasta @ ₹360.0
Added 1 x Biryani | Total: ₹370.0
========================================
RECEIPT
========================================
Margherita Pizza (₹399.0) - General
Cold Coffee (₹150.0) - Beverages
Garlic Bread (₹129.0) - General
Garlic Bread (₹129.0) - General
Pasta (₹360.0) - Discounted
Biryani (₹320.0) - Main Course (Express)
----------------------------------------
Total: ₹1487.0
========================================
Total items in cart: 6
Why Use Method Overloading? (Real Project Benefits)
|
Use Case |
Benefit |
|---|---|
|
placeOrder(name, price) |
Quick order for simple items |
|
placeOrder(name, price, category) |
Better analytics (track by category) |
|
placeOrder(name, price, quantity) |
Bulk ordering |
|
placeOrder(name, price, discount) |
Promotional offers |
|
placeOrder(..., express) |
Premium delivery option |
Clean, intuitive API for developers and users.
How Java Chooses the Right Method?
|
Call |
Method Selected |
|---|---|
|
placeOrder("Pizza", 399) |
(String, double) |
|
placeOrder("Coffee", 150, "Drinks") |
(String, double, String) |
|
placeOrder("Bread", 129, 2) |
(String, double, int) |
Common Mistakes
// NOT overloading (only return type differs)
public int calculate() { ... }
public double calculate() { ... } // COMPILE ERROR!
// Valid overloading
public void add(int a, int b) { }
public void add(double a, double b) { }
public void add(int a, int b, int c) { }
Real-Time Use Cases
|
System |
Overloaded Method |
|---|---|
|
Banking App |
deposit(amount), deposit(amount, accountType) |
|
Email System |
send(to), send(to, cc, subject, body) |
|
Graphics |
draw(shape), draw(shape, color, size) |
|
Logger |
log(message), log(message, level, timestamp) |
Summary
-
Method Overloading = Same name, different parameters.
-
Improves API design and code readability.
-
Used in real projects for flexible, user-friendly methods.
-
Compile-time decision — fast and safe.
Project Tip:
In your Food Delivery App, overload:
-
applyCoupon(code)
-
applyCoupon(code, minOrderValue)
-
applyCoupon(code, userType)
Q: Why is method overloading called compile-time polymorphism?
A: Because the method call is resolved by the compiler during compilation, not at runtime.
You now master Method Overloading in Java with a real-world, production-ready example!
Keep building — happy coding!