Codectionary / Developer documentation / Java

Abstract Classes

An abstract class is a class that cannot be instantiated directly and may contain both fully implemented methods and abstract methods (declared without a body, which subclasses must implement). Abstract classes sit between interfaces and regular classes: like an interface, they define a contract; like a regular class, they can hold state (fields) and provide shared, already-implemented behavior.

Syntax

abstract class ClassName {\n  abstract returnType methodName();\n}

Examples

Basic Abstract Class

Defining a base class that mixes concrete and abstract methods.

public abstract class Animal {
    protected String name;

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

    public abstract void makeSound();  // no body - subclasses must implement

    public void sleep() {  // concrete method, shared by all subclasses
        System.out.println(name + " is sleeping");
    }
}

public class Dog extends Animal {
    public Dog(String name) {
        super(name);
    }

    @Override
    public void makeSound() {
        System.out.println(name + " says: Woof!");
    }
}

// Animal a = new Animal("Generic");  // Error - can't instantiate abstract class
Dog dog = new Dog("Rex");
dog.makeSound();
dog.sleep();

Enforcing a Common Structure

Multiple subclasses implementing the same abstract method differently.

abstract class Employee {
    protected String name;
    protected double baseSalary;

    public Employee(String name, double baseSalary) {
        this.name = name;
        this.baseSalary = baseSalary;
    }

    public abstract double calculateBonus();

    public double totalPay() {
        return baseSalary + calculateBonus();
    }
}

class Manager extends Employee {
    public Manager(String name, double baseSalary) {
        super(name, baseSalary);
    }

    @Override
    public double calculateBonus() {
        return baseSalary * 0.2;
    }
}

class Developer extends Employee {
    public Developer(String name, double baseSalary) {
        super(name, baseSalary);
    }

    @Override
    public double calculateBonus() {
        return baseSalary * 0.1;
    }
}

Employee m = new Manager("Fola", 60000);
System.out.println(m.totalPay());  // 72000.0

Abstract Class vs Interface

A quick illustration of when each is more appropriate.

// Interface: unrelated classes sharing a capability, no shared state
interface Flyable {
    void fly();
}

// Abstract class: closely related classes sharing state AND behavior
abstract class Bird {
    protected String species;

    public Bird(String species) {
        this.species = species;
    }

    public abstract void layEggs();

    public void breathe() {
        System.out.println(species + " is breathing");
    }
}

class Eagle extends Bird implements Flyable {
    public Eagle() {
        super("Eagle");
    }

    public void layEggs() {
        System.out.println("Eagle laying eggs");
    }

    public void fly() {
        System.out.println("Eagle soaring high");
    }
}

Best practices

  • Use an abstract class when subclasses share both state (fields) and some common implemented behavior, not just a method signature
  • Use an interface instead when unrelated classes just need to share a capability, with no shared fields or implementation
  • A class can only extend one abstract class but can implement multiple interfaces - factor that into your design choice
  • Make a method abstract only when every subclass genuinely needs its own distinct implementation - otherwise provide a sensible default in the abstract class itself

At a glance

Purpose
General-purpose application development
File extension
.java
Runs in
Java Virtual Machine
Usually used with
JDK and Java libraries

Specifications & further reading

Related Java documentation

Classes
Classes in Java are blueprints for creating objects, defining their properties (fields) and behaviors (methods). Java is a strictly object-oriented language where everything is encapsulated within classes. A class serves as a template that specifies what data an object will store and what operations it can perform.
Interfaces
An interface defines a contract of methods that implementing classes must provide, without specifying how those methods work internally. Unlike a class, an interface cannot be instantiated directly - it only declares what a class can do, not how. A class uses the 'implements' keyword to fulfill an interface's contract, and a single class can implement multiple interfaces, which is Java's way of achieving a form of multiple inheritance.
Constructors
A constructor is a special method that runs automatically when an object is created with 'new', typically used to initialize the object's fields. A constructor shares its name with the class and has no return type, not even void. Java supports constructor overloading, letting a class offer multiple ways to construct an object, and constructor chaining with this(...), where one constructor calls another in the same class.
Access Modifiers
Access modifiers control the visibility of classes, fields, and methods from other parts of a program. Java has four levels: public (accessible from anywhere), protected (accessible within the same package and by subclasses), default/package-private (accessible only within the same package, used when no modifier is written), and private (accessible only within the declaring class itself).