OBJECT-ORIENTED FOUNDATIONS / OBJECT DESIGN BRIEF

Interfaces and abstract classes

An interface declares what operations a type supports without implementing them; any class can implement many interfaces.

BeginnerPhase 01 / Topic 7 of 7ResponsibilitiesCollaborationsExtensibility
01

Overview

An interface declares what operations a type supports without implementing them; any class can implement many interfaces. An abstract class can contain both implemented and abstract methods plus state, but a class can extend only one (in Java, C#, TypeScript).

Use interfaces to define capabilities and contracts between components (Notifier, Repository), which keeps coupling low and allows multiple implementations and test fakes. Use abstract classes to share code and state among closely related subclasses, often as a Template Method skeleton. In interviews, starting from interfaces is almost always the stronger design.

A job description vs a partially trained apprentice

An interface is a job description: anyone who can do these tasks qualifies. An abstract class is an apprentice who already knows some skills and needs to learn the rest; you can only have one master to learn from.

02

When to use it

  • Interface: a capability many unrelated classes might have (Comparable, Payable).
  • Interface: boundaries between modules, for dependency inversion and testing.
  • Abstract class: shared state and algorithm skeleton for a family of classes.
03

Where it shows up in interviews

Contract-first design

Recognize it when: define boundaries before implementations.

  • Design a payment gateway
  • Design a storage abstraction
Shared skeleton

Recognize it when: subclasses repeat the same steps with small differences.

  • Design report exporters
  • Design a data import pipeline
04

Where it is used in real software

Java Collections

List is an interface; AbstractList is an abstract class that implements most of it so ArrayList and others only fill in a few methods.

Go interfaces

Go uses implicit interfaces like io.Reader, satisfied by any type with the right methods.

TypeScript structural typing

Any object with matching members satisfies an interface, which makes fakes in tests trivial.

05

Key terms

Interface
Contract of method signatures; multiple can be implemented.
Abstract class
Cannot be instantiated; may have state and implemented methods.
Default method
Java interface method with a body, for evolving interfaces.
Abstract method
Declared without a body; subclasses must implement.
06

How it works, step by step

  1. 1
    Start with the interface

    What does the caller need?

  2. 2
    Keep it small and cohesive

    Split fat interfaces (ISP).

  3. 3
    Add an abstract base only for real shared code

    Common state or algorithm skeleton.

  4. 4
    Implement concrete classes

    Extend the base or implement the interface directly.

  5. 5
    Depend on the interface in callers

    Never on the abstract base unless required.

07

Interface vs abstract class

Key differences (Java / TypeScript)

Step 1 / 5
AspectInterfaceAbstract class
Multiple inheritanceImplement manyExtend one
State (fields)Constants only (Java)Yes
ConstructorsNoYes
Implemented methodsDefault methods (Java 8+)Yes
Best forCapabilities and boundariesShared code in a family

NOWAspect: Multiple inheritance | Interface: Implement many | Abstract class: Extend one

Common combination: an interface as the public contract, plus an optional abstract base implementing shared parts.

08

Implementation

public interface Exporter {    byte[] export(List<Row> rows);} // Abstract base: shared skeleton for text-based exporterspublic abstract class TextExporter implements Exporter {    @Override    public final byte[] export(List<Row> rows) {        StringBuilder out = new StringBuilder(header());        for (Row row : rows) out.append(formatRow(row)).append('\n');        return out.toString().getBytes(StandardCharsets.UTF_8);    }    protected abstract String header();    protected abstract String formatRow(Row row);} public final class CsvExporter extends TextExporter {    protected String header() { return "id,name,total\n"; }    protected String formatRow(Row r) { return r.id() + "," + r.name() + "," + r.total(); }} // A binary exporter implements the interface directly, no base class neededpublic final class ParquetExporter implements Exporter {    public byte[] export(List<Row> rows) { return ParquetWriter.write(rows); }}
09

Complexity and performance

Interfaces per classMany

Mix capabilities.

Abstract parents per classOne

Single inheritance.

10

Trade-offs

Flexibility vs reuse

Interfaces maximize flexibility; abstract classes maximize code reuse but couple subclasses to the base.

Evolving contracts

Adding a method to an interface breaks implementers unless a default is provided.

11

Variants and related techniques

Functional interfaces

Single-method interfaces usable with lambdas (Comparator, Runnable).

Marker interfaces

No methods, only a type tag (Serializable); annotations are often better.

12

Common mistakes

  • Depending on the abstract base in callers.

    Fix: Depend on the interface so other implementations remain possible.

  • Fat interfaces.

    Fix: Split into role interfaces.

13

Interview questions

When would you choose an abstract class over an interface?

When closely related subclasses share state or a fixed algorithm skeleton that should be implemented once. For contracts between components or capabilities across unrelated classes, use interfaces.

Can Java interfaces have implementations?

Yes, since Java 8 they can have default and static methods, and since Java 9 private methods, but they still cannot hold instance state.

14

Practice problems

ProblemDifficultyWhat it trains
Design Exporter for CSV, JSON, PDFEasyInterface + base.
Design a Shape hierarchy with Drawable and ResizableEasyMultiple interfaces.