← Back to Java series
🧱
OOP
OOP Β· Prerequisite: previous lecture

08. Inheritance

Inheritance lets a child class **reuse and extend** the parent's structure and behavior with the `extends` keyword. This lecture covers `extends`, `super`, the `@Override` annotation, and method overriding.

JavaOOPobject-orientedinheritance
Duration
⏱ ~1.5-2 hours
Level
πŸ“Š Beginner-Intermediate
Prerequisite
🎯 Previous lecture or equivalent knowledge
OUTCOME
Inheritance lets a child class **reuse and extend** the parent's structure and behavior with the `extends` keyword. This lecture covers `extends`, `super`, the `@Override` annotation, and method overriding.

What you'll learn

  • 1Define a parent-child relationship with `extends`
  • 2Call the parent constructor with `super(...)`
  • 3Override methods correctly with `@Override`
  • 4Understand single inheritance and the `Object` root class
  • 5Block extension with `final`

Overview

Inheritance lets a child class **reuse and extend** the parent's structure and behavior with the `extends` keyword. This lecture covers `extends`, `super`, the `@Override` annotation, and method overriding.

Core Concepts

1) `extends`

java
class Animal {
    String name;
    Animal(String name) { this.name = name; }
    void speak() { System.out.println(name + " makes a sound"); }
}

class Dog extends Animal {
    Dog(String name) { super(name); }
    @Override
    void speak() { System.out.println(name + " says Woof!"); }
}
  • `Dog` inherits the fields and methods of `Animal`
  • `super(name)` calls the parent constructor
  • `@Override` lets the compiler verify you really are overriding

2) Method overriding

A child class can redefine a parent method **with the same signature**. At runtime, the actual object's implementation runs (polymorphism β€” covered in lecture 09).

3) `super`

java
class Child extends Parent {
    @Override
    void doWork() {
        super.doWork();           // call parent's implementation
        System.out.println("extra"); // then add child behavior
    }
}

4) `Object` root

Every class in Java implicitly inherits from `Object`. That's why every object has `toString()`, `equals()`, `hashCode()`.

5) `final` class / `final` method

  • `final class X` prevents extension (e.g. `String`, `Integer`)
  • `final` method prevents overriding

Examples

Example 1 β€” `AnimalDog.java`: basic inheritance and override

java
public class AnimalDog {
    static class Animal {
        String name;
        Animal(String name) { this.name = name; }
        void speak() { System.out.println(name + " makes a sound"); }
    }

    static class Dog extends Animal {
        Dog(String name) { super(name); }
        @Override
        void speak() { System.out.println(name + " says Woof!"); }
    }

    public static void main(String[] args) {
        Animal a = new Animal("Generic");
        Dog d = new Dog("Rex");
        a.speak();
        d.speak();
    }
}

**Output**

text
Generic makes a sound
Rex says Woof!

**Note:** without `@Override` a typo silently creates a brand-new method.

Example 2 β€” `SuperCall.java`: calling the parent first

java
public class SuperCall {
    static class Base {
        void log() { System.out.println("Base.log"); }
    }
    static class Sub extends Base {
        @Override
        void log() {
            super.log();
            System.out.println("Sub.log");
        }
    }

    public static void main(String[] args) {
        new Sub().log();
    }
}

**Output**

text
Base.log
Sub.log

**Note:** `super.method()` invokes the parent's implementation explicitly.

Example 3 β€” `ObjectToString.java`: the `Object.toString` you always get

java
public class ObjectToString {
    static class Point {
        int x, y;
        Point(int x, int y) { this.x = x; this.y = y; }
        @Override
        public String toString() { return "Point(" + x + "," + y + ")"; }
    }

    public static void main(String[] args) {
        Point p = new Point(1, 2);
        System.out.println(p);              // calls toString implicitly
        System.out.println("p = " + p);     // toString again via +
    }
}

**Output**

text
Point(1,2)
p = Point(1,2)

**Note:** override `toString` for human-readable debug output.

Example 4 β€” `FinalDemo.java`: blocking extension with `final`

java
public class FinalDemo {
    static final class Sealed {
        void hello() { System.out.println("hello"); }
    }

    // class Tries extends Sealed {}  // compile error: cannot inherit from final

    public static void main(String[] args) {
        new Sealed().hello();
    }
}

**Output**

text
hello

**Note:** the JDK uses `final` for value types like `String` / `Integer`.

Common Mistakes

  1. Forgetting `super(...)` when the parent has no no-arg constructor
  2. Misspelling a method name β†’ it becomes a new method instead of an override (add `@Override`)
  3. Trying to extend a `final` class
  4. Confusing inheritance with composition β€” favor composition when behavior, not type, is shared
  5. Accessing `private` parent fields directly from a child (use `protected` or getters)

Summary

  • Inherit with `extends`, call the parent with `super(...)`
  • Override with the same signature; use `@Override` to be safe
  • Java has **single inheritance** (one parent class, but multiple interfaces β€” lecture 10)

Practice

# Practice - 08. Inheritance

## Exercise 1 β€” `Shape` hierarchy

  • File: `Homework01.java`
  • Key concepts: `extends`, override `area()`

Requirements

  • Parent class `Shape` with `String name` and `double area() { return 0; }`.
  • Children `Rectangle(w, h)` and `Circle(r)` override `area()`.
  • In main, store both in `Shape[]` and print each name + area.

Expected output

text
rect: 12.0
circle: 12.566

## Exercise 2 β€” `Employee` / `Manager`

  • File: `Homework02.java`
  • Key concepts: `super`, field reuse

Requirements

  • Class `Employee(String name, long salary)` with `String describe()` β†’ `name(salary)`.
  • Class `Manager(String name, long salary, int teamSize) extends Employee` overrides `describe()` to append ` team=N`.

Expected output

text
Jisoo(3000000)
Minsu(5000000) team=4

## Solutions After trying it yourself, compare with [`answer/`](./answer/).

Solution code (homework/answer/)

answer/Homework01.java

java
/** Shape hierarchy. */
public class Homework01 {
    public static void main(String[] args) {
        Shape[] shapes = { new Rectangle(3, 4), new Circle(2) };
        for (Shape s : shapes) System.out.printf("%s: %.3f%n", s.name, s.area());
    }
}

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

answer/Homework02.java

java
/** Employee / Manager. */
public class Homework02 {
    public static void main(String[] args) {
        System.out.println(new Employee("Jisoo", 3_000_000).describe());
        System.out.println(new Manager("Minsu", 5_000_000, 4).describe());
    }
}

class Employee {
    String name; long salary;
    Employee(String name, long salary) { this.name = name; this.salary = salary; }
    String describe() { return name + "(" + salary + ")"; }
}
class Manager extends Employee {
    int teamSize;
    Manager(String name, long salary, int teamSize) {
        super(name, salary);
        this.teamSize = teamSize;
    }
    @Override
    String describe() { return super.describe() + " team=" + teamSize; }
}

Try It Yourself

bash
cd 02_oop/08_inheritance/src
javac AnimalDog.java
java AnimalDog

Next Lecture

[09_Polymorphism](../09_λ‹€ν˜•μ„±/) β€” parent-reference / child-object, `instanceof`, pattern matching.

Example code / lecture materials

All lecture materials and example code are openly available on GitHub.

View on GitHub β†—