Inheritance in Java β€” <code>extends</code> and <code>super</code>

Inheritance is a Java mechanism for reusing and specialising an existing class. A subclass gets all non-private members of its parent and can add new ones or override existing behaviour. Java allows single inheritance only β€” a class extends at most one other class β€” but can implement any number of interfaces.

Basic syntax

public class Animal {
    protected String name;
    public Animal(String name) { this.name = name; }
    public String speak() { return name + " makes a sound"; }
}

public class Dog extends Animal {
    private final String breed;

    public Dog(String name, String breed) {
        super(name);                 // call parent constructor
        this.breed = breed;
    }

    @Override
    public String speak() {
        return name + " barks";       // overrides Animal.speak
    }
}

What's inherited

MemberInherited?
public, protected methodsβœ…
public, protected fieldsβœ…
Package-private methods/fields (same package only)βœ… (same package)
private members❌
Constructors❌ (must call with super(...))
static methodsInherited but not overridden β€” hidden if redefined

Constructor chaining

The first statement of every constructor is an implicit or explicit super(...) call. If the parent has no no-arg constructor, you must call super(...) explicitly with arguments.

Overriding rules

  • Same name and parameter list as the parent method.
  • Return type must be the same or a subtype (covariant return).
  • Cannot be more restrictive in access (a protected method can be overridden to public, not to private).
  • Cannot throw new or broader checked exceptions.
  • Always use @Override β€” the compiler catches typo-overrides that silently create new methods.

final, abstract, sealed

public final class Money { ... }        // can't be subclassed
public abstract class Shape { ... }      // must be subclassed, can't instantiate
public sealed class Shape permits Circle, Square {}  // Java 17+ β€” closed hierarchy

Favour composition

Inheritance models is-a ("a Dog is an Animal"). Most reuse relationships are actually has-a β€” a Car has an Engine, not is. Use composition (a field + delegation) unless the is-a is literal and the parent is designed for extension.

// Composition β€” flexible, decoupled
public class Car {
    private final Engine engine;
    public Car(Engine engine) { this.engine = engine; }
    public void start() { engine.ignite(); }
}

Common mistakes

  • Missing @Override β€” a typo creates a parallel method. Always annotate.
  • Protected fields β€” breaks encapsulation. Keep fields private; expose protected methods if subclasses truly need access.
  • Deep hierarchies β€” three levels is usually too many. Prefer composition or interfaces.
  • Calling overridable methods from a constructor β€” subclass override runs before the subclass is fully initialised. Make such methods final.

Related

Pillar: OOP in Java. Siblings: polymorphism, abstraction, sealed classes.