Skip to content

Lab: a catalog on an abstract blueprint

☕ Java 17 · Blueprints You Can't Instantiate · 3/3

Goal: build a small streaming catalog on two abstract classes, where each concrete class fills in only what is left.

Setup: create AbstractCatalog.java (no package). All classes go in this file. Compile with javac AbstractCatalog.java, run with java AbstractCatalog.

Step 1 — The blueprint and a movie

abstract class Content {
    abstract String title();
    abstract int minutes();

    String summary() {
        return title() + ": " + minutes() + " min";
    }
}

class Movie extends Content {
    String title() { return "Inception"; }
    int minutes() { return 148; }
}

public class AbstractCatalog {
    public static void main(String[] args) {
        Content movie = new Movie();
        System.out.println(movie.summary());
    }
}
  • title() and minutes() are abstract: Content has no idea what they return.
  • summary() is a normal method that relies on them anyway: the real object will provide the values.
  • Movie is concrete, so it must implement both abstract methods. It inherits summary().
  • new Content() would never compile, but a Content variable can hold any concrete child.
Inception: 148 min

Step 2 — A second family: series

Add below Movie:

abstract class Series extends Content {
    abstract int episodes();
    int minutes() { return episodes() * 45; }
}

class MiniSeries extends Series {
    String title() { return "Chernobyl"; }
    int episodes() { return 5; }
}
  • Series is abstract too. It adds an abstract episodes() and implements minutes() from it.
  • Series doesn't implement title(): an abstract class may leave methods for its children.
  • MiniSeries is the first concrete class of this branch, so it implements everything still abstract: title() and episodes(). It doesn't rewrite minutes().

In main, add:

        Content show = new MiniSeries();
        System.out.println(show.summary());
Inception: 148 min
Chernobyl: 225 min

Follow the second line: summary() in Content calls title() (from MiniSeries) and minutes() (from Series), which calls episodes() (from MiniSeries): 5 × 45 = 225.

Final code

abstract class Content {
    abstract String title();
    abstract int minutes();

    String summary() {
        return title() + ": " + minutes() + " min";
    }
}

class Movie extends Content {
    String title() { return "Inception"; }
    int minutes() { return 148; }
}

abstract class Series extends Content {
    abstract int episodes();
    int minutes() { return episodes() * 45; }
}

class MiniSeries extends Series {
    String title() { return "Chernobyl"; }
    int episodes() { return 5; }
}

public class AbstractCatalog {
    public static void main(String[] args) {
        Content movie = new Movie();
        System.out.println(movie.summary());
        Content show = new MiniSeries();
        System.out.println(show.summary());
    }
}

Full code on GitHub

← Concrete classes and the rules · Back to the series


🎓 Preparing the OCP Java 17 exam? Exam traps and practice questions for this section → (optional)