Skip to main content

Section 9.3 Interfaces vs. Abstract Classes

An interface is a purely abstract contract specifying methods a class must implement. Interfaces differ from abstract classes in two crucial ways:
  • They cannot contain instance fields (except for constants)
  • A class can implement multiple interfaces simultaneously
Like abstract classes, interfaces cannot be instantiated directly since they define responsibilities without providing implementations. They are declared using the interface keyword:
// Simple interface definition
public interface Printable {
    void print(); // Implicitly public and abstract
}

// Interface with a constant
public interface Taxable {
    double TAX_RATE = 0.07; // Implicitly public, static, and final
    
    double calculateTax(); // Calculate tax for this item
}
Note that interface methods are implicitly public and abstract, and any fields are implicitly public, static, and final (constants). This means interfaces cannot store per-instance state.

Note 9.3.1. Interfaces Cannot Be Instantiated.

Like abstract classes, interfaces cannot be instantiated directly. This makes sense since they contain no implementation for their methods (except for default methods).
// These won't compile:
Printable p = new Printable();       // Error
Taxable t = new Taxable();           // Error
You must always create a concrete class that implements the interface, then instantiate that class.
To use an interface, a class "implements" it:
// A class implementing an interface
public class Product implements Taxable {
    private String name;
    private double price;
    
    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }
    
    @Override
    public double calculateTax() {
        return price * TAX_RATE;
    }
}
The power of interfaces becomes apparent when we implement multiple interfaces:
// A class implementing multiple interfaces
public class Invoice implements Printable, Taxable {
    private String customer;
    private double amount;
    
    // Constructor and other methods omitted for brevity
    
    @Override
    public void print() {
        System.out.println("Invoice for: " + customer);
        System.out.println("Amount: $" + amount);
        System.out.println("Tax: $" + calculateTax());
    }
    
    @Override
    public double calculateTax() {
        return amount * TAX_RATE;
    }
}

Note 9.3.2. Modern Java Feature: Default Methods.

Since Java 8, interfaces can include default methods. Default methods are methods with implementations. They were introduced primarily to enable interface evolution without breaking existing code. Before Java 8, adding a new method to an interface would break all existing implementations.
public interface Sortable {
    // Abstract method (no implementation)
    void sort();
    
    // Default method (with implementation)
    default void sortDescending() {
        System.out.println("Default implementation - using sort() in reverse");
        sort();  // Note: calls the abstract method that implementers must provide
        // Reverse the order...
    }
}
Even with default methods, interfaces still cannot contain instance fields. Default methods should generally be used for:
  • Adding optional functionality that builds on the core abstract methods
  • Providing convenience methods that implementers shouldn’t need to override
  • Evolving existing interfaces without breaking backward compatibility
Caution: Default methods should not be used to implement significant shared logic. That’s what abstract classes are for. Default methods were primarily introduced to allow interfaces to evolve over time without breaking existing code. Overusing them can lead to:
  • Blurred distinction between interfaces and abstract classes
  • Poor design where state management becomes difficult
  • Confusion about where behavior is defined
  • Maintenance issues when multiple interfaces provide conflicting default implementations
Key takeaways about interfaces:
  • Interfaces define a contract that implementing classes must fulfill
  • Interface methods are implicitly public and abstract
  • Interfaces cannot have instance fields (only constants)
  • Interfaces cannot have constructors (since they don’t initialize instance state)
  • A class can implement multiple interfaces (unlike inheritance, which is limited to one superclass)
  • Default methods provide a way to add methods to interfaces without breaking existing implementations

Exercises Exercises

1.

How does an abstract class differ from an interface?
  • An abstract class can have instance fields, while an interface cannot.
  • Correct! Abstract classes can have instance variables, while interfaces only allow constants (public static final).
  • An abstract class can implement multiple interfaces, while an interface can extend only one abstract class.
  • Incorrect. Interfaces can extend multiple interfaces, while a class can extend only one abstract class.
  • An abstract class cannot have any implemented methods, whereas an interface can.
  • Incorrect. Abstract classes can have implemented methods, while interfaces only allow default or static methods.
  • An abstract class must provide implementations for all its methods, while an interface does not.
  • Incorrect. Abstract classes can have abstract methods, which must be implemented by subclasses.

2.

When should you use an interface instead of an abstract class?
  • When you want to enforce method signatures across unrelated classes.
  • Correct! Interfaces are ideal for defining common behavior across unrelated class hierarchies.
  • When you need to store instance fields and state.
  • Incorrect. Interfaces do not support instance fields; only abstract classes can have state.
  • When you want to limit a class to implementing only one type of behavior.
  • Incorrect. A class can implement multiple interfaces, whereas it can only extend one abstract class.
  • When you need to define a class hierarchy with shared concrete methods
  • Incorrect. Abstract classes are better suited for defining common functionality in a class hierarchy.

3.

Which statement is true regarding constructors in interfaces and abstract classes?
  • Both interfaces and abstract classes can have constructors
  • Incorrect. Interfaces cannot have constructors, while abstract classes can.
  • Neither interfaces nor abstract classes can have constructors.
  • Incorrect. Abstract classes can have constructors to initialize instance fields.
  • Abstract classes can have constructors, but interfaces cannot
  • Correct! Abstract classes can define constructors, whereas interfaces cannot because they don’t manage instance state.
  • Interfaces can have private constructors to restrict instantiation.
  • Incorrect. Interfaces cannot have constructors at all.
You have attempted of activities on this page.