# Inheritance and Polymorphism in Java — extends, super, Overriding

Source: https://skills101.in/learn/java/java-inheritance-and-polymorphism — Skills101 free tutorial (Java Programming). Updated 2026-11-09.

**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](https://skills101.in/learn-img/java/inheritance-tree.svg)

## 1. extends and super

```java
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());
    }
}
```

```text
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.

```java
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);
    }
}
```

```text
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)

| | Overloading | Overriding |
|---|---|---|
| Where | same class | parent and child class |
| Method name | same | same |
| Parameters | **different** | **same** |
| Decided at | compile time (static) | runtime (dynamic) |
| Also called | compile-time polymorphism | runtime polymorphism |

## 4. Upcasting, downcasting and instanceof

```java
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());
        }
    }
}
```

```text
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 quiz and free certificate: https://skills101.in/learn/java/java-inheritance-and-polymorphism