Skip to content

Java Inheritance, Overriding and Overloading

Inheritance is one of the cornerstones of object-oriented programming, allowing us to create hierarchical class structures and achieve code reuse. Closely related to inheritance is method overriding, while another easily confused concept is method overloading. This chapter will explain the relationships and differences between these three concepts in detail.

Inheritance

Inheritance allows one class (subclass) to acquire the non-private attributes and methods of another class (parent class). Subclasses can use parent class members as if they were their own.

  • Superclass: Also called base class, is the class being inherited from.
  • Subclass: Also called derived class, is the class that inherits from the parent class.

In Java, the extends keyword is used to implement inheritance.

java
// Parent class
public class Vehicle {
    String brand;

    public void start() {
        System.out.println("Vehicle started!");
    }
}

// Subclass Car inherits from Vehicle
public class Car extends Vehicle {
    String model;

    public void honk() {
        System.out.println("Beep beep! The car is honking.");
    }
}

// Usage
Car myCar = new Car();
myCar.brand = "Toyota"; // Access attribute inherited from parent class
myCar.model = "Camry";
myCar.start(); // Call method inherited from parent class
myCar.honk();  // Call subclass's own method

The super Keyword

The super keyword is used to reference members of the direct parent class from within a subclass.

  1. Calling parent class constructor: super() must be the first statement in a subclass constructor, used to call the parent class constructor.
  2. Calling parent class methods: super.methodName() can be used to call the parent class version of a method that has been overridden in the subclass.
java
public class Animal {
    String name;

    public Animal(String name) {
        this.name = name;
        System.out.println("Animal constructor called");
    }

    public void eat() {
        System.out.println(name + " is eating");
    }
}

public class Dog extends Animal {
    public Dog(String name) {
        super(name); // 1. Call parent class constructor
        System.out.println("Dog constructor called");
    }

    @Override
    public void eat() {
        super.eat(); // 2. Call parent class eat() method
        System.out.println(name + " is chewing a bone");
    }
}

Method Overriding

When a subclass is not satisfied with a particular method implementation provided by the parent class, it can provide its own version of the method with the same name and parameters. This process is called method overriding.

Overriding Rules:

  • Method name and parameter list must be exactly the same as the parent class.
  • The subclass's return type must be the same as or a subtype of the parent class's return type.
  • The access modifier of the subclass method cannot be more restrictive than that of the parent class method (e.g., if parent is public, subclass cannot be protected).
  • It's recommended to use the @Override annotation, which allows the compiler to check if this is a valid override.
java
class Shape {
    public void draw() {
        System.out.println("Drawing a shape");
    }
}

class Circle extends Shape {
    @Override // Tell the compiler I want to override the parent's method
    public void draw() {
        System.out.println("Drawing a circle ○");
    }
}

Method Overloading

Method overloading means that within the same class, you can have multiple methods with the same name, as long as their parameter lists are different (different in number, type, or order of parameters). Overloading is unrelated to return type.

java
public class Printer {
    public void print(String text) {
        System.out.println(text);
    }

    // Overload print method to accept different parameter types
    public void print(int number) {
        System.out.println(number);
    }

    // Overload print method to accept different number of parameters
    public void print(String text, int times) {
        for (int i = 0; i < times; i++) {
            System.out.println(text);
        }
    }
}

Overriding vs. Overloading

This is a very important comparison in Java and a common interview question.

FeatureMethod OverridingMethod Overloading
PurposeSubclass changes parent's behaviorProvide multiple similarly-functioning methods with same name in one class
LocationOccurs between parent and child classesOccurs within the same class
Method SignatureMethod name and parameter list must be identicalMethod name is same, but parameter list must be different
Return TypeReturn type must be same or a subtypeCan be different
PolymorphismDemonstrates runtime polymorphismDemonstrates compile-time polymorphism
KeywordsInvolves extends and superNo specific keywords

Applications of the final Keyword

  • final method: If a method in a parent class is declared as final, it cannot be overridden by any subclass.

    java
    public class Parent {
        public final void lockMethod() {
            // ...
        }
    }
  • final class: If a class is declared as final, it cannot be inherited by any class. For example, Java's String class is final.

    java
    public final class Uninheritable {
        // ...
    }

Content is for learning and research only.