Unit 3 · OOP Concepts

3.8.3Abstract class or interface?

FeatureAbstract classInterface
Keywordabstract class / extendsinterface / implements
MethodsAbstract and concreteAbstract, plus default and static (Java 8+) and private (Java 9+)
AttributesAny kindConstants only (public static final)
ConstructorsYesNo
InheritanceA class extends only oneA class can implement many
Best forRelated classes sharing code (is-a)Unrelated classes sharing a capability (can-do)
«abstract»Employee# name: String+ calculateSalary(): double+ display()FullTimemonthly: doublecalculateSalary()PartTimehours, ratecalculateSalary()«interface»PayableMAX_LIMIT = 100000pay(double amount)receipt() (default)CardPayment+ pay(double)implementsextends
An abstract class (italic name) shares code with related subclasses; an interface is a contract that any class can implement (dashed arrow)

Example: Bird, Aeroplane and Drone are unrelated but all are Flyable (interface). Dog, Cat and Bird are related and can share the abstract class Animal.

A quick decision guide

Ask these questions in order:

  1. Do the classes share code or state (attributes, constructors, methods with bodies)? If yes, an abstract class lets you write that code once.
  2. Is it an is-a relationship within one family? (A FullTime is an Employee.) If yes, an abstract class fits.
  3. Is it a capability that unrelated classes can have? (A Bird, a Drone and an Aeroplane can fly.) If yes, use an interface.
  4. Does a class need more than one type? (A Duck is an Animal, is Flyable and is Swimmable.) It can only extend one class, so use interfaces for the extra types.

When in doubt, start with an interface. It is the more flexible choice, because any class can implement it, whatever it already extends.

Using both together

Real designs often combine the two: an interface defines the contract, and an abstract class provides a partial implementation that subclasses can reuse.

Java
interface Shape { double area(); double perimeter(); }

abstract class BaseShape implements Shape {
    protected String colour;
    BaseShape(String colour) { this.colour = colour; }
    public String describe() { return colour + " shape, area " + area(); }
}

class Square extends BaseShape {
    private double side;
    Square(String colour, double side) { super(colour); this.side = side; }
    public double area()      { return side * side; }
    public double perimeter() { return 4 * side; }
}

Other code works with the Shape interface; BaseShape saves each shape from repeating the colour code; and Square supplies only what is specific to squares.

Remember

  • Abstract class: related classes, shared code, is-a, single inheritance.
  • Interface: any classes, a shared capability, can-do, many per class.
  • They can be combined: an interface for the contract, an abstract class for the shared code.