Skills101

Java Programming · Lesson 8 of 15 · Updated ·

Inheritance and Polymorphism in Java — extends, super, Overriding

Inheritance lets a class reuse another class's fields and methods. Polymorphism lets one piece of code work with many related types. Together they are the heart of Java OOP.

Employee is the parent class with name, salary and work(); Developer, Manager and Intern extend it and each add their own field. A Manager is an Employee

1. extends and super

class Employee {
    String name;
    double salary;
    Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }
    String work() { return name + " is working"; }
}

class Manager extends Employee {
    int teamSize;
    Manager(String name, double salary, int teamSize) {
        super(name, salary);          // must be the first line
        this.teamSize = teamSize;
    }
    @Override
    String work() { return super.work() + " and managing " + teamSize + " people"; }
}

public class Main {
    public static void main(String[] args) {
        System.out.println(new Employee("Ravi", 40000).work());
        System.out.println(new Manager("Neha", 90000, 5).work());
    }
}
Ravi is working
Neha is working and managing 5 people
  • class Manager extends Employee — Manager is an Employee.
  • super(...) calls the parent constructor; super.work() calls the parent's method.
  • @Override asks the compiler to check that you really are overriding.

Java supports single inheritance of classes (one parent), but a class can implement many interfaces (next lesson).

2. Runtime polymorphism

A parent-type variable can hold a child object. When you call an overridden method, Java runs the child's version — decided at runtime.

class Shape {
    double area() { return 0; }
}
class Circle extends Shape {
    double r;
    Circle(double r) { this.r = r; }
    @Override double area() { return Math.PI * r * r; }
}
class Rectangle extends Shape {
    double w, h;
    Rectangle(double w, double h) { this.w = w; this.h = h; }
    @Override double area() { return w * h; }
}

public class Main {
    public static void main(String[] args) {
        Shape[] shapes = { new Circle(1), new Rectangle(3, 4), new Circle(2) };
        double total = 0;
        for (Shape s : shapes) {
            total += s.area();          // the right area() runs for each object
        }
        System.out.printf("%.2f%n", total);
    }
}
27.71

The loop doesn't know or care which shape it has. Add a Triangle class later and this loop works without changes. That's the power of polymorphism.

3. Overloading vs overriding (most asked)

OverloadingOverriding
Wheresame classparent and child class
Method namesamesame
Parametersdifferentsame
Decided atcompile time (static)runtime (dynamic)
Also calledcompile-time polymorphismruntime polymorphism

4. Upcasting, downcasting and instanceof

class Animal { String sound() { return "..."; } }
class Dog extends Animal {
    @Override String sound() { return "Woof"; }
    String fetch() { return "fetching"; }
}

public class Main {
    public static void main(String[] args) {
        Animal a = new Dog();            // upcasting: automatic
        System.out.println(a.sound());   // Dog's version
        if (a instanceof Dog d) {        // check, then downcast (Java 16+ pattern)
            System.out.println(d.fetch());
        }
    }
}
Woof
fetching

Through an Animal variable you can only call methods that Animal declares; to call fetch() you must downcast — after checking with instanceof.

5. The final keyword

  • final variable → can't be reassigned (a constant).
  • final method → can't be overridden.
  • final class → can't be extended (String is final).

Common mistakes

  • Forgetting super(...) when the parent has no no-argument constructor (compile error).
  • Thinking a parent variable can call child-only methods without a cast.
  • Changing parameters while trying to override (that's overloading — use @Override to catch it).

Quick recap

  • extends = is-a; super reaches the parent.
  • Overriding + parent-type variables = runtime polymorphism.
  • Overloading (compile time) vs overriding (runtime).
  • instanceof before downcasting; final stops changes.

Practice what you learned

📝 Quiz: Inheritance and Polymorphism5 questions · instant answers & explanations · +10 XP · counts towards your free certificateTake the quiz →