Notifications

No notifications

/Phase 3

Inheritance, Interfaces & Polymorphism

Java is built around classes. Inheritance lets a class reuse another class's code with extends; interfaces let unrelated classes share a contract with implements; polymorphism lets one variable refer to many concrete types. Together they're the backbone of every real Java codebase — Spring, Android SDK, the JDK itself.

On this page

Detailed Theory

# Inheritance, Interfaces, Polymorphism

extends — single inheritance

Java only allows extending one class.
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); } // call parent ctor @Override void speak() { System.out.println(name + " barks"); } }

@Override is not optional in practice — it makes the compiler verify you actually overrode something.

abstract class — partial implementation

abstract class Shape {
    abstract double area();          // no body — subclass must provide
    void describe() { System.out.println("area = " + area()); }
}

class Circle extends Shape { double r; Circle(double r) { this.r = r; } @Override double area() { return Math.PI * r * r; } }

You cannot new Shape() — only its concrete subclasses.

interface — pure contract

interface Drawable {
    void draw();                      // implicitly public abstract
    default void clear() {            // Java 8+ default method
        System.out.println("clearing");
    }
    static Drawable empty() {         // Java 8+ static method
        return () -> {};
    }
}

class Button implements Drawable { @Override public void draw() { System.out.println("button"); } }

A class can implements many interfaces — that's how Java does multiple inheritance of *behaviour*.

Polymorphism

Animal a = new Dog("Rex");   // upcast — variable type Animal, runtime type Dog
a.speak();                    // "Rex barks" — dispatched to Dog.speak()
The compiler checks the declared type; the JVM dispatches on the actual type. This is *dynamic dispatch* / *runtime polymorphism*.

Comparable & Comparator

class Player implements Comparable<Player> {
    int score;
    @Override public int compareTo(Player o) { return Integer.compare(this.score, o.score); }
}

Comparator<Player> byScoreDesc = (a, b) -> Integer.compare(b.score, a.score);

final, sealed, instanceof pattern (modern Java)

  • final class X — cannot be extended.
  • final void m() — cannot be overridden.
  • sealed class Shape permits Circle, Square (Java 17+) — limits which classes may extend it.
  • if (a instanceof Dog d) d.bark(); (Java 16+ pattern) — test + cast in one go.