Menu
Coddy logo textTech

Method Overriding (@Override)

Part of the Object Oriented Programming section of Coddy's Java journey — lesson 22 of 87.

Method overriding allows a subclass to provide its own implementation of a method that's already defined in its parent class. This is how child classes customize inherited behavior to suit their specific needs.

When you override a method, the subclass version completely replaces the parent's version for objects of that subclass. The method must have the same name, return type, and parameters as the parent method:

public class Animal {
    public void makeSound() {
        System.out.println("Some generic sound");
    }
}

public class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Woof!");
    }
}

public class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Meow!");
    }
}

The @Override annotation tells the compiler you intend to override a parent method. While optional, it's strongly recommended because the compiler will catch errors if you accidentally misspell the method name or use wrong parameters:

@Override
public void makeSound() { }  // Correct - compiler verifies this

public void makesound() { }  // Typo! Creates new method instead of overriding

When you call an overridden method, Java executes the version that belongs to the actual object type:

Dog dog = new Dog();
dog.makeSound();  // Output: Woof!

Cat cat = new Cat();
cat.makeSound();  // Output: Meow!

Remember from the previous lesson that you can use super.methodName() inside an overridden method if you still want to include the parent's behavior along with your new code.

challenge icon

Challenge

Easy

Let's build a notification system that demonstrates how subclasses can override parent methods to provide their own specialized behavior. You'll see how the @Override annotation helps catch mistakes and how each subclass can customize inherited methods.

You'll create three files to organize your code:

  • Notification.java: Create the parent class that represents a generic notification. It should have:
    • A private field for the message (String)
    • A constructor that accepts the message
    • A method getMessage() that returns the message
    • A method send() that prints: Sending notification: [message]
  • EmailNotification.java: Create a subclass that extends Notification and customizes how notifications are sent via email:
    • A private field for the recipient email address (String)
    • A constructor that takes both the message and recipient, using super(message) for the parent portion
    • Override the send() method using the @Override annotation to print: Emailing [recipient]: [message]
  • Main.java: Demonstrate how the same method name produces different behavior depending on the object type. You'll receive two inputs: a message and an email address. Create both a regular Notification and an EmailNotification with the same message, then call send() on each to see the different outputs.

You will receive two inputs: the message (String) and the recipient email address (String).

Your output should show two lines - first from the parent's send() method, then from the overridden version in EmailNotification. This demonstrates how method overriding lets subclasses replace inherited behavior with their own implementation.

Cheat sheet

Method overriding allows a subclass to provide its own implementation of a method already defined in its parent class. The overridden method must have the same name, return type, and parameters as the parent method.

public class Animal {
    public void makeSound() {
        System.out.println("Some generic sound");
    }
}

public class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Woof!");
    }
}

The @Override annotation is optional but strongly recommended. It tells the compiler you intend to override a parent method, helping catch errors like misspelled method names or incorrect parameters:

@Override
public void makeSound() { }  // Correct - compiler verifies this

public void makesound() { }  // Typo! Creates new method instead of overriding

When calling an overridden method, Java executes the version that belongs to the actual object type:

Dog dog = new Dog();
dog.makeSound();  // Output: Woof!

Cat cat = new Cat();
cat.makeSound();  // Output: Meow!

You can use super.methodName() inside an overridden method to include the parent's behavior along with your new code.

Try it yourself

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Read inputs
        String message = scanner.nextLine();
        String recipient = scanner.nextLine();
        
        // TODO: Create a Notification object with the message
        
        // TODO: Create an EmailNotification object with the message and recipient
        
        // TODO: Call send() on the Notification object
        
        // TODO: Call send() on the EmailNotification object
    }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming