Course topics

By WebNest Studio Engineering Team

Java - Core Tutorial

Java Inheritance

Inheritance is the OOP mechanism that lets one class (the subclass or child class) acquire the fields and methods of another class (the superclass or parent class) using the extends keyword. It models an "is-a" relationship — a Car is a Vehicle, a Savings Account is a Bank Account — and it allows common behavior to be written once in a parent class and reused by every subclass, rather than duplicated.

Why it matters

Inheritance lets one class build on another instead of copying it, and it is the foundation that polymorphism stands on. It is also easy to overuse: a subclass is tied to every detail of its parent. Knowing exactly what is and is not inherited — and that Java allows only one superclass — helps you decide when "is a" really applies.

Watch: Core Java Inheritance Concept

A walkthrough of inheritance in core Java: how a child class extends a parent class, what it inherits, and how it reuses the parent's code.

Watch on YouTube

What Gets Inherited

A subclass automatically inherits the non-private fields and methods of its superclass, meaning it can use them as if they were declared in the subclass itself. Private members of the superclass exist in the subclass's memory layout but are not directly accessible by name from the subclass — they can only be reached indirectly through public or protected methods the superclass provides. Constructors are never inherited, but a subclass constructor always invokes a superclass constructor (implicitly or via super(...)) before running its own body.

Single Inheritance Only, for Classes

Java deliberately supports only single inheritance for classes — a class can extend exactly one direct superclass, never more than one. This avoids the "diamond problem" that arises in languages with multiple class inheritance, where ambiguity occurs if two parent classes define a conflicting method. A class can, however, implement multiple interfaces, which is how Java achieves a safe form of multiple inheritance of type without inheriting conflicting implementation.

The Inheritance Chain and Object

Every class in Java, if it does not explicitly extend another class, implicitly extends java.lang.Object, which is why every object has methods like toString(), equals(), and hashCode() available by default. Inheritance can also be chained across multiple levels (a class extending a class that extends another class), and a subclass inherits members from every class above it in that chain.

  • Use extends for a class to inherit from exactly one superclass.
  • A subclass gains access to public and protected superclass members directly by name.
  • Every class ultimately inherits from java.lang.Object if it extends nothing else.

Types of Inheritance in Java

Inheritance is usually described in five shapes. Java classes support three of them directly. The other two are possible only through interfaces.

  • Single: one class extends one class, such as Car extends Vehicle.
  • Multilevel: a chain, such as Dog extends Mammal and Mammal extends Animal. Dog inherits from both classes above it.
  • Hierarchical: several classes extend the same parent, such as Car, Bike and Truck all extending Vehicle.
  • Multiple: one class with two parents. Classes cannot do this, but a class can implement several interfaces: class Duck implements Flyer, Swimmer.
  • Hybrid: a mix of the shapes above. Java allows it only when the multiple-parent part uses interfaces.

Constructor Order in an Inheritance Chain

When you create a subclass object, the constructors run from the top of the chain down. Each constructor first calls its parent's constructor through super(...), written by you or inserted by the compiler, so the Object part is built first, then each parent, and the subclass last. This guarantees that inherited fields are set up before the subclass code uses them. In the multilevel example below, creating a Dog prints the Animal, Mammal and Dog constructor messages in that order.

Access Modifiers Across the Hierarchy

The access modifier on a member decides whether a subclass can use it by name.

  • public: visible to the subclass and to everyone else.
  • protected: visible to subclasses, even in other packages, and to classes in the same package. Use it for members meant for subclasses.
  • Default (no modifier): visible only to subclasses in the same package.
  • private: never visible by name in a subclass. Reach it through a public or protected method of the parent.

Examples

A subclass inheriting and extending superclass behavior

Java
class Vehicle {
    String brand = "Generic";

    void start() {
        System.out.println(brand + " vehicle starting");
    }
}

class Car extends Vehicle {
    int numberOfDoors = 4;

    void honk() {
        System.out.println(brand + " car honking with " + numberOfDoors + " doors");
    }
}

public class InheritanceDemo {
    public static void main(String[] args) {
        Car myCar = new Car();
        myCar.brand = "Toyota";
        myCar.start(); // inherited from Vehicle
        myCar.honk();  // defined in Car
    }
}
Output
Toyota vehicle starting
Toyota car honking with 4 doors

Multilevel inheritance: constructors run top-down, and Dog inherits from every class above it

Java
public class MultilevelDemo {
    public static void main(String[] args) {
        Dog dog = new Dog("Rex");
        dog.eat();     // from Animal
        dog.breathe(); // from Mammal
        dog.bark();    // from Dog
        System.out.println(dog instanceof Animal);
    }
}

class Animal {
    protected String name;

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

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

class Mammal extends Animal {
    Mammal(String name) {
        super(name);
        System.out.println("Mammal constructor");
    }

    void breathe() {
        System.out.println(name + " breathes air");
    }
}

class Dog extends Mammal {
    Dog(String name) {
        super(name);
        System.out.println("Dog constructor");
    }

    void bark() {
        System.out.println(name + " says woof");
    }
}
Output
Animal constructor
Mammal constructor
Dog constructor
Rex is eating
Rex breathes air
Rex says woof
true

Common Mistakes

  • Trying to make a class extend two classes at once (e.g. "class C extends A, B") — Java does not allow multiple class inheritance.
  • Assuming private superclass fields are directly accessible in the subclass by name, when they are only reachable through inherited public/protected accessors.
  • Forgetting that constructors are not inherited — a subclass must define its own constructors, even if they just call super().
  • Confusing "is-a" (inheritance, extends) with "has-a" (composition, a field of another class type) and inheriting when composition would model the relationship more accurately.

Exercise

Create a SavingsAccount that extends Account and adds a method addInterest(int percent), which increases the balance by that percentage. The subclass should reuse the inherited balance field.

Expected output: 1050

Java · starter code
class Account {
    protected int balance;

    Account(int balance) {
        this.balance = balance;
    }

    int getBalance() {
        return balance;
    }
}

// TODO: class SavingsAccount extends Account, with a constructor and addInterest(int percent)

public class AccountDemo {
    public static void main(String[] args) {
        SavingsAccount savings = new SavingsAccount(1000);
        savings.addInterest(5);
        System.out.println(savings.getBalance());
    }
}
Show hints
  • The subclass constructor must pass the opening balance up with super(balance);.
  • Because balance is protected, the subclass can update it directly: balance += balance * percent / 100;.
Show solution
Java · solution
class Account {
    protected int balance;

    Account(int balance) {
        this.balance = balance;
    }

    int getBalance() {
        return balance;
    }
}

class SavingsAccount extends Account {

    SavingsAccount(int balance) {
        super(balance);
    }

    void addInterest(int percent) {
        balance += balance * percent / 100;
    }
}

public class AccountDemo {
    public static void main(String[] args) {
        SavingsAccount savings = new SavingsAccount(1000);
        savings.addInterest(5);
        System.out.println(savings.getBalance()); // 1050
    }
}

Quick quiz

1. How many classes can a Java class extend directly?

  • A. One
  • B. Two
  • C. Any number
  • D. None
Show answer

A. Java supports single inheritance of classes. A class can implement many interfaces, but extend only one class.

2. Can a subclass access a private field of its superclass directly?

  • A. Yes, always
  • B. Only if both are in the same file
  • C. Only inside its constructor
  • D. No; it needs a getter, setter or other accessible method
Show answer

D. Private members are visible only inside the class that declares them. The subclass object still contains the field but cannot name it.

3. Are constructors inherited by a subclass?

  • A. Yes, all of them
  • B. Only the no-argument constructor
  • C. Only public ones
  • D. No, but the subclass can call them with super(...)
Show answer

D. Constructors are not members and are not inherited. Each class declares its own, and a subclass constructor invokes a superclass constructor.

Interview questions

Which types of inheritance does Java support?

Show answer

Single inheritance (one class extends another), multilevel inheritance (A extends B, B extends C), and hierarchical inheritance (several classes extend the same parent). Multiple inheritance of classes is not allowed. A class can, however, implement several interfaces, which gives multiple inheritance of type.

What is the difference between an IS-A and a HAS-A relationship?

Show answer

IS-A is inheritance: a SavingsAccount is an Account, expressed with extends or implements. HAS-A is composition or aggregation: a Car has an Engine, expressed as a field. If you cannot honestly say "X is a Y" in every situation, use a field instead of inheritance.

Key Points to Remember

  • Inheritance lets a subclass reuse fields and methods of a superclass via "extends", modeling an "is-a" relationship.
  • Java allows only single inheritance between classes, but a class can implement multiple interfaces.
  • Constructors are not inherited, and every class ultimately extends java.lang.Object.
  • Java classes support single, multilevel and hierarchical inheritance; multiple and hybrid inheritance need interfaces.
  • Constructors in a chain run from the top superclass down to the subclass.

Practice in the playground

Write and run your own code for this topic, or start from the exercise or an example. Runs plain Java 17. Frameworks such as Spring, and databases, are not available here. Your code for each topic is kept in this browser.

Run the examples

Change an input, predict the result, then compare it with the output. Explain why the result changes.

WebNest Studio

Written by

WebNest Studio Engineering Team

Practical lessons from developers working with Java, Python, React, databases and production systems.

Led by Vansh Duggal, Founder, WebNest Studio · Full-stack & software engineering