Method Overriding: Changing the Script
In Inheritance, a subclass gets everything the parent has. But sometimes, a child class doesn't want to do things exactly like its parent. Method Overriding allows a subclass to provide a specific implementation of a method that is already defined in its superclass.
1. The Golden Rules of Overriding
To successfully override a method, you must follow these rules:
- Same Name: The method name must be identical to the one in the parent.
- Same Parameters: The arguments (inputs) must be exactly the same.
- Same Return Type: You can't change what the method gives back.
- The "is-a" Relationship: Overriding only works through inheritance (using
extends).
2. The @Override Annotation
While not strictly required by the compiler, you should always put @Override above your method. It tells Java: "I am intentionally changing a parent method. If I make a typo in the name, please show me an error!"
class Animal {
void makeSquareSound() {
System.out.println("Generic animal sound");
}
}
class Dog extends Animal {
@Override
void makeSquareSound() {
System.out.println("Bark! Bark!");
}
}
3. Why Use Overriding? (Polymorphism)
Overriding is the foundation of Polymorphism. It allows you to treat different objects as their parent type, but they still act like themselves.
Imagine you have an array of Animal objects. When you call .makeSquareSound(), the Dog barks and the Cat meows, even though you are looking at them as just "Animals."
💻 Full Practical Example: The Payment System
Copy this code to see how different payment types calculate their own fees:
class Payment {
double amount;
Payment(double amount) {
this.amount = amount;
}
// Default: No extra fee
void processPayment() {
System.out.println("Processing payment of $" + amount);
}
}
class CreditCard extends Payment {
CreditCard(double amount) {
super(amount);
}
@Override
void processPayment() {
double fee = amount * 0.03; // 3% fee for credit cards
System.out.println("Processing Credit Card (Fee: $" + fee + "). Total: $" + (amount + fee));
}
}
class Cash extends Payment {
Cash(double amount) {
super(amount);
}
@Override
void processPayment() {
System.out.println("Processing Cash payment of $" + amount + " (No fee).");
}
}
public class Main {
public static void main(String[] args) {
Payment p1 = new CreditCard(100.0);
Payment p2 = new Cash(100.0);
p1.processPayment(); // Runs the CreditCard version
p2.processPayment(); // Runs the Cash version
}
}
⚠️ Things You CANNOT Override
- Static Methods: They belong to the class, not the object.
- Final Methods: If a method is marked
finalin the parent, the child is forbidden from changing it. - Private Methods: The child can't see them, so it can't override them.
💡 Challenge: The Game Character
- Create a class
Characterwith a methodattack(). - Create a subclass
Warriorthat overridesattack()to print "Warrior swings a heavy sword!". - Create a subclass
Magethat overridesattack()to print "Mage casts a fireball!". - In
main, create one of each and make them attack!