thecodex.expert · The Codex Family of Knowledge
Java

Interfaces and Abstract Classes

A class can implement as many interfaces as it wants, but extend only one class — that single restriction is the whole reason interfaces exist as a separate concept.

Java 21 LTS default methods since Java 8 Last verified:
Canonical Definition

An abstract class (declared with abstract) can mix fully-implemented methods, abstract method signatures with no body, and instance fields, but a class can only extend one abstract (or concrete) class — Java has no multiple class inheritance. An interface historically held only abstract method signatures and constants, but since Java 8 it can also declare default methods (with a body, inherited by implementers) and static methods; a class can implement any number of interfaces, which is the real reason interfaces exist as a separate mechanism.

Abstract classes: partial implementation, single inheritance

A subclass extending Shape must implement area(), but inherits describe() as-is — abstract classes are the right tool when subclasses genuinely share both state and some common behavior.

JavaShape.java
public abstract class Shape {
    protected String name;   // shared state, inherited by subclasses

    public Shape(String name) {
        this.name = name;
    }

    public abstract double area();   // no body — subclasses MUST implement this

    public String describe() {        // fully implemented — inherited as-is
        return name + " has area " + area();
    }
}

public class Circle extends Shape {
    private double radius;
    public Circle(double radius) { super("Circle"); this.radius = radius; }
    public double area() { return Math.PI * radius * radius; }   // required implementation
}

Interfaces: multiple inheritance of behavior

A class can implement any number of interfaces — this is the capability abstract classes fundamentally cannot offer, since Java allows only one class in the extends chain.

JavaFlyable.java
public interface Flyable {
    void fly();
}

public interface Swimmable {
    void swim();
}

public class Duck implements Flyable, Swimmable {   // implements BOTH
    public void fly() { System.out.println("Flying"); }
    public void swim() { System.out.println("Swimming"); }
}

default methods: interfaces with real implementation (Java 8+)

Before Java 8, adding a new method to an interface would break every existing implementer; default provides a fallback implementation so old code keeps compiling — this is precisely why the interface change was added, to evolve APIs like the Collections framework without breaking backward compatibility.

JavaGreeter.java
public interface Greeter {
    String name();

    default String greet() {           // default method: real implementation
        return "Hello, " + name() + "!";
    }
}

public class Person implements Greeter {
    public String name() { return "Alice"; }
    // no need to implement greet() — the default is inherited
}

Sources

1
Oracle. The Java Tutorials, "Interfaces and Inheritance," docs.oracle.com/javase/tutorial/java/IandI.