Inheritance & Polymorphism

Inheritance & the extends Keyword

15 min Lesson 1 of 14

Inheritance & the extends Keyword

One of the most powerful ideas in object-oriented programming is inheritance — the ability for one class to automatically receive the fields and methods of another class. Instead of writing the same code in five places, you write it once in a superclass and let every related subclass reuse it for free.

The Is-A Relationship

Before you touch the keyboard, ask one question: does my new class represent a more specific version of an existing class? If a Dog is a kind of Animal, that is an is-a relationship, and inheritance is the right tool. If a Car has an Engine, that is a has-a relationship — use composition instead (we cover that in a later lesson).

  • Dog is a Animal — good fit for inheritance.
  • SavingsAccount is a BankAccount — good fit.
  • Car has an Engine — use composition, not inheritance.
The is-a test is the most important design check. Applying inheritance where composition belongs produces fragile, confusing code. Ask the question every time before using extends.

Superclass and Subclass

In Java the class being inherited from is called the superclass (also called parent class or base class). The class that inherits is called the subclass (also child class or derived class). You create the relationship with the extends keyword.

// Superclass public class Animal { String name; int age; public void eat() { System.out.println(name + " is eating."); } public void sleep() { System.out.println(name + " is sleeping."); } } // Subclass public class Dog extends Animal { String breed; public void bark() { System.out.println(name + " says: Woof!"); } }

Dog extends Animal, so every Dog object automatically has name, age, eat(), and sleep() — without a single extra line inside the Dog class. The Dog class only defines what makes a dog different from a generic animal: the breed field and the bark() method.

What Gets Inherited

A subclass inherits everything that the superclass declares with public or protected access. Concretely:

  • Instance fieldsname and age in the example above.
  • Instance methodseat() and sleep().
  • Static (class) members — also inherited, though static methods are not polymorphically dispatched.

What is not inherited:

  • Private members — fields and methods marked private exist in the superclass object but are not directly accessible from the subclass.
  • Constructors — constructors are never inherited; the subclass must define its own (or the compiler adds a default one). You can call the superclass constructor using super(), which we cover in the next lesson.
Private fields are not accessible, but they are still there. When you create a Dog, the underlying Animal portion of the object is fully initialised. You just cannot read or write private superclass fields directly; use protected or public getters instead.

A Runnable Example

Let us put it all together and run it:

public class Main { public static void main(String[] args) { Dog myDog = new Dog(); myDog.name = "Buddy"; // inherited from Animal myDog.age = 3; // inherited from Animal myDog.breed = "Labrador"; // defined in Dog myDog.eat(); // inherited method myDog.sleep(); // inherited method myDog.bark(); // Dog's own method } }

Output:

Buddy is eating. Buddy is sleeping. Buddy says: Woof!

Dog did not define eat() or sleep(), yet we call them on a Dog instance without any issues. That is inheritance at work.

Extending a Chain: Multi-Level Inheritance

Java allows a subclass to itself be extended. You can have AnimalDogGuideDog. Each level inherits everything from all levels above it.

public class GuideDog extends Dog { String owner; public void guide() { System.out.println(name + " is guiding " + owner); } }

A GuideDog object now has name, age, breed, eat(), sleep(), bark(), and guide() — all accumulated across three levels.

Keep inheritance hierarchies shallow. More than two or three levels deep is usually a sign that the design needs rethinking. Deep chains are hard to read, hard to test, and brittle when requirements change.

Why Inheritance Matters

Inheritance gives you three concrete benefits:

  1. Code reuse — write shared behaviour once in the superclass instead of duplicating it across many classes.
  2. Extensibility — add a new kind of Animal by creating a new subclass; the shared code does not change.
  3. Polymorphism — a variable of type Animal can hold a Dog, a Cat, or any other subclass. This is the topic of Lesson 5 and it unlocks some of Java's most powerful patterns.

Summary

Use the extends keyword when a new class has a genuine is-a relationship with an existing class. The subclass inherits all public and protected members of the superclass and adds its own specialisations on top. Constructors and private members are not inherited. In the next lesson we will look at super and how to call the superclass constructor properly.