JavaAbstract Classes

Abstract Classes

An abstract class is a class that cannot be instantiated on its own — it exists to be extended. You mark it with the abstract keyword, and it can contain abstract methods: methods declared with no body, whose implementation is deferred to whichever concrete subclass extends the abstract class.

Declaring an abstract class and method

Shape.java

Java
abstract class Shape {
    // Abstract method — no body, just a signature. Every concrete
    // subclass MUST provide an implementation.
    abstract double area();

    // Concrete method — abstract classes can absolutely have these too.
    void printArea() {
        System.out.println("Area = " + area());
    }
}

The rule is simple: if a class declares even one abstract method, the class itself must be declared abstract. The compiler enforces this — you can't sneak an unimplemented method into an ordinary class.

You cannot instantiate an abstract class
Warning
Trying to create an instance of an abstract class directly with `new` is a compile-time error, because the class is by definition incomplete — it has methods with no bodies. It only becomes usable once a concrete subclass fills in the missing pieces.

This does not compile

Java
Shape s = new Shape(); // error: Shape is abstract; cannot be instantiated
Extending with concrete subclasses

A subclass that extends an abstract class must implement every abstract method it inherits, or be declared abstract itself. Once all abstract methods are implemented, the subclass is concrete and can be instantiated normally.

Circle.java and Rectangle.java

Java
class Circle extends Shape {
    private final double radius;

    Circle(double radius) {
        this.radius = radius;
    }

    @Override
    double area() {
        return Math.PI * radius * radius;
    }
}

class Rectangle extends Shape {
    private final double width;
    private final double height;

    Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    @Override
    double area() {
        return width * height;
    }
}

public class Main {
    public static void main(String[] args) {
        Shape[] shapes = { new Circle(3), new Rectangle(4, 5) };
        for (Shape shape : shapes) {
            shape.printArea(); // uses each shape's own area() implementation
        }
    }
}
Fields and constructors are allowed too

Unlike interfaces before Java 8, abstract classes have always been able to hold instance fields, constructors, and fully-implemented (concrete) methods, in addition to abstract ones. This makes them a good fit when related subclasses share real state or behavior, not just a shared signature — for example, every Shape above could hold a common name field set through a constructor that every subclass calls with super(name).

Note
Abstract classes support only single inheritance — a class can extend just one abstract (or any) class. When you need multiple independent contracts on the same class, or the class in question doesn't fit neatly into a single hierarchy, reach for **Interfaces** instead — see the dedicated page for the full comparison.
  • A class with any abstract method must itself be abstract.

  • Abstract classes cannot be instantiated with new.

  • Abstract classes can mix abstract methods with concrete methods, fields, and constructors.

  • A concrete subclass must implement every inherited abstract method.