×

Advanced Coding & Software Engineering Program

Duration: 1 Year (12 Months)

Join our premium 1-year program to master cutting-edge technologies and become an industry-ready Software Engineer!

Course Coverage

  • Languages: C, C++, Java, JavaScript, Python
  • Web Technologies: HTML, CSS, Bootstrap 5, MERN Stack, Full Stack Development
  • Databases: MySQL, MongoDB
  • Data Science Libraries: Pandas, NumPy
  • Development Tools: Visual Studio Code, IntelliJ IDEA, PyCharm, Postman, Git, GitHub
  • Cloud Platforms: Vercel, MongoDB Atlas

Program Highlights

  • Live Classes: Interactive sessions with real-time doubt resolution
  • Hands-On Sessions: Practical coding exercises to build real-world skills
  • Industry Experts: Learn from professionals with years of experience
  • Live Project: Work on real-world projects to apply your skills
  • Get Certificate: Earn a professional certificate upon program completion

Course Fee: Only ₹1020 / month
Limited Period Offer!

Java Method Overriding Tutorial with Real-Time Project Example



Last Updated on: 12th Nov 2025 15:08:29 PM

Welcome to this beginner-friendly tutorial on Method Overriding in Java! Method Overriding is a runtime polymorphism feature that allows a subclass to provide a specific implementation of a method that is already defined in its superclass.

 

This tutorial uses a real-world project-based example — a Banking System with Multiple Account Types — to show how method overriding is used in production software.

 

What is Method Overriding?

Method Overriding occurs when a subclass provides a new implementation of a method that is already defined in its superclass. The method in the subclass must have:

  • Same name

  • Same parameter list

  • Same return type (or covariant return type)

 

It is used to change or modify the behavior of an inherited method.

 

👉 It represents Runtime Polymorphism (also known as Dynamic Polymorphism).

 

Decided at runtime (Runtime Polymorphism)
Enables dynamic behavior
Uses @Override annotation (recommended)

 

Rules for Method Overriding

  1. Method must be inherited (not private, final, or static)

  2. Same name, parameters, and return type

  3. Subclass method cannot reduce visibility (e.g., public private)

  4. Use @Override to catch errors

  5. Can throw fewer or narrower exceptions

 

Example of Method Overriding

class Vehicle {
    void run() {
        System.out.println("The vehicle is running...");
    }
}

class Bike extends Vehicle {
    @Override
    void run() {
        System.out.println("The bike is running at 60 km/h.");
    }
}

class Car extends Vehicle {
    @Override
    void run() {
        System.out.println("The car is running at 100 km/h.");
    }
}

public class VehicleTest {
    public static void main(String[] args) {
        Vehicle v1 = new Bike();  // runtime decision
        Vehicle v2 = new Car();

        v1.run();  // Calls Bike’s run()
        v2.run();  // Calls Car’s run()
    }
}

 

Output 

The bike is running at 60 km/h.
The car is running at 100 km/h.

 

How Method Overriding Works Internally

  • The reference variable of the parent class points to a child class object.

  • At runtime, the JVM decides which method to call based on the actual object type, not the reference type.

  • This behavior is known as Dynamic Method Dispatch.

 

Important Points to Remember

   Keyword    Description
 @Override  Ensures that you’re actually overriding a parent method (compiler checked).
 super  Can be used inside the child class to call the parent class method.
 final  If a method is final, it cannot be overridden.
 static  Static methods are hidden, not overridden.

 

Example: Using super Keyword

class Animal {
    void sound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    @Override
    void sound() {
        super.sound(); // Call parent method
        System.out.println("Dog barks");
    }
}

public class SuperExample {
    public static void main(String[] args) {
        Dog d = new Dog();
        d.sound();
    }
}

 

Output

Animal makes a sound
Dog barks

 

Real-Time Project: Banking System

Let’s build a Banking Application that supports:

  • Savings Account (with interest)

  • Current Account (with overdraft)

  • Fixed Deposit Account (locked funds)

We’ll use method overriding to calculate interest and withdrawal rules differently for each account type.

 

Step 1: Superclass – BankAccount

// BankAccount.java
public class BankAccount {
    protected String accountNumber;
    protected String holderName;
    protected double balance;

    public BankAccount(String accountNumber, String holderName, double initialBalance) {
        this.accountNumber = accountNumber;
        this.holderName = holderName;
        this.balance = initialBalance;
    }

    // Common method - can be overridden
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            System.out.println("Deposited: ₹" + amount + " | New Balance: ₹" + balance);
        } else {
            System.out.println("Invalid deposit amount.");
        }
    }

    // Method to be overridden
    public void withdraw(double amount) {
        if (amount > 0 && amount <= balance) {
            balance -= amount;
            System.out.println("Withdrawn: ₹" + amount + " | Remaining: ₹" + balance);
        } else {
            System.out.println("Insufficient funds or invalid amount.");
        }
    }

    // Method to be overridden
    public void calculateInterest() {
        System.out.println("No interest applicable for basic account.");
    }

    // Display account info
    public void displayInfo() {
        System.out.println("Account: " + accountNumber);
        System.out.println("Holder: " + holderName);
        System.out.println("Balance: ₹" + balance);
    }
}

 

Step 2: Subclasses with Overridden Methods

 

1. SavingsAccount.java

public class SavingsAccount extends BankAccount {
    private double interestRate = 4.0; // 4% per year

    public SavingsAccount(String accountNumber, String holderName, double initialBalance) {
        super(accountNumber, holderName, initialBalance);
    }

    @Override
    public void withdraw(double amount) {
        double minBalance = 1000;
        if (amount > 0 && (balance - amount) >= minBalance) {
            balance -= amount;
            System.out.println("[Savings] Withdrawn: ₹" + amount + " | Balance: ₹" + balance + " (Min ₹1000 maintained)");
        } else {
            System.out.println("[Savings] Withdrawal failed: Minimum balance ₹1000 required.");
        }
    }

    @Override
    public void calculateInterest() {
        double interest = balance * (interestRate / 100);
        balance += interest;
        System.out.println("[Savings] Interest added: ₹" + interest + " | New Balance: ₹" + balance);
    }
}

 

2. CurrentAccount.java

public class CurrentAccount extends BankAccount {
    private double overdraftLimit = 5000;

    public CurrentAccount(String accountNumber, String holderName, double initialBalance) {
        super(accountNumber, holderName, initialBalance);
    }

    @Override
    public void withdraw(double amount) {
        double maxWithdraw = balance + overdraftLimit;
        if (amount > 0 && amount <= maxWithdraw) {
            balance -= amount;
            System.out.println("[Current] Withdrawn: ₹" + amount + " | Balance: ₹" + balance + " (Overdraft used if negative)");
        } else {
            System.out.println("[Current] Withdrawal exceeds overdraft limit of ₹5000.");
        }
    }

    @Override
    public void calculateInterest() {
        System.out.println("[Current] No interest on current accounts.");
    }
}

 

3. FixedDepositAccount.java

public class FixedDepositAccount extends BankAccount {
    private double interestRate = 7.5;
    private boolean isMatured = false;

    public FixedDepositAccount(String accountNumber, String holderName, double initialBalance) {
        super(accountNumber, holderName, initialBalance);
    }

    @Override
    public void withdraw(double amount) {
        if (isMatured) {
            super.withdraw(amount); // Use parent's logic
        } else {
            System.out.println("[FD] Withdrawal not allowed: FD not matured yet!");
        }
    }

    @Override
    public void calculateInterest() {
        double interest = balance * (interestRate / 100);
        balance += interest;
        System.out.println("[FD] High interest added: ₹" + interest + " | Total: ₹" + balance);
    }

    public void matureFD() {
        isMatured = true;
        System.out.println("[FD] Fixed Deposit matured. Withdrawal now allowed.");
    }
}

 

Step 3: Main App – BankingSystem

// BankingSystem.java
import java.util.ArrayList;
import java.util.List;

public class BankingSystem {
    public static void main(String[] args) {
        // Polymorphic List
        List<BankAccount> accounts = new ArrayList<>();
        
        accounts.add(new SavingsAccount("SAV001", "Amit Sharma", 5000));
        accounts.add(new CurrentAccount("CUR001", "Priya Verma", 10000));
        accounts.add(new FixedDepositAccount("FD001", "Raj Patel", 50000));

        System.out.println("BANKING SYSTEM - MONTHLY PROCESSING\n");

        // Runtime Polymorphism in action
        for (BankAccount account : accounts) {
            account.displayInfo();
            account.deposit(1000);
            account.withdraw(2000);
            account.calculateInterest();
            System.out.println("-".repeat(50));
        }

        // Special case: Mature FD
        FixedDepositAccount fd = (FixedDepositAccount) accounts.get(2);
        fd.matureFD();
        fd.withdraw(10000);
    }
}

 

Output

BANKING SYSTEM - MONTHLY PROCESSING

Account: SAV001
Holder: Amit Sharma
Balance: ₹5000.0
Deposited: ₹1000.0 | New Balance: ₹6000.0
[Savings] Withdrawn: ₹2000.0 | Balance: ₹4000.0 (Min ₹1000 maintained)
[Savings] Interest added: ₹160.0 | New Balance: ₹4160.0
--------------------------------------------------
Account: CUR001
Holder: Priya Verma
Balance: ₹10000.0
Deposited: ₹1000.0 | New Balance: ₹11000.0
[Current] Withdrawn: ₹2000.0 | Balance: ₹9000.0 (Overdraft used if negative)
[Current] No interest on current accounts.
--------------------------------------------------
Account: FD001
Holder: Raj Patel
Balance: ₹50000.0
Deposited: ₹1000.0 | New Balance: ₹51000.0
[FD] Withdrawal not allowed: FD not matured yet!
[FD] High interest added: ₹3825.0 | Total: ₹54825.0
--------------------------------------------------
[FD] Fixed Deposit matured. Withdrawal now allowed.
Withdrawn: ₹10000.0 | Remaining: ₹44825.0

 

Why Use Method Overriding? (Real Project Benefits)

      Feature

      Benefit

  withdraw()

  Different rules per account type

  calculateInterest()

  Unique logic for each account

  Runtime Decision

  Correct method called based on actual object

  Extensible

  Add StudentAccount, NRIAccount easily

 

 How Java Chooses the Right Method?

     Object

     Method Called

 new SavingsAccount()

 SavingsAccount.withdraw()

 new CurrentAccount()

 CurrentAccount.withdraw()

 

JVM decides at runtime using vtable (virtual method table).

 

Real-Time Use Cases

     System

     Overridden Method

 Payment Gateway

 processPayment() in CreditCard, UPI, Wallet

 Notification System

 send() in Email, SMS, Push

 Report Generator

 generate() in PDFReport, ExcelReport

 Vehicle System

 startEngine() in ElectricCar, PetrolCar

 

Common Mistakes

// NOT overriding
public void deposit(int amount) { }  // Different parameter type

// Valid override
@Override
public void deposit(double amount) { }  // Same signature

 

// Cannot override final method
class A { final void lock() {} }
class B extends A { void lock() {} }  // ERROR

 

Summary

  • Method Overriding allows a subclass to modify behavior of its superclass method.

  • It enables runtime polymorphism, improving flexibility and reusability.

  • Always use the @Override annotation for clarity and safety.

  • It’s one of the most important OOP concepts in Java.

 

Project Tip:
In your Banking App, override:

  • applyCharges() for different account types

  • sendAlert() for SMS/email preferences

  • generateStatement() for PDF/HTML

 


You now master Method Overriding in Java with a real-world, scalable banking system!
Keep building — happy coding!  yes


Online - Chat Now
Let’s Connect

Inquiry Sent!

Your message has been successfully sent. We'll get back to you soon!

iKeySkills Logo