Java Abstraction

Abstraction is the practice of hiding complex details and exposing only what a caller needs to know. In Java you achieve it with abstract classes and abstract methods. An abstract class describes what a group of related objects can do, while leaving the exact how to each concrete subclass.

Abstract classes and abstract methods

An abstract class is declared with the abstract keyword. You cannot create an object from it directly, because it is incomplete on purpose. It exists to be extended. Inside it you can declare abstract methods, which have a signature but no body. Any concrete subclass is required to provide a body for every abstract method it inherits.

  • An abstract class may contain both abstract methods (no body) and normal methods (with a body).
  • You cannot instantiate an abstract class with new.
  • A subclass must override every abstract method, or it too must be declared abstract.
  • Abstract classes can have constructors, fields, and static members like any other class.

Declaring an abstract class

abstract class Vehicle {
  // abstract method: no body, subclasses must fill it in
  public abstract void start();

  // regular method shared by all vehicles
  public void fuelUp() {
    System.out.println("Filling the tank");
  }
}

class Car extends Vehicle {
  @Override
  public void start() {
    System.out.println("Turn the key, engine runs");
  }
}

public class Main {
  public static void main(String[] args) {
    // Vehicle v = new Vehicle(); // error: cannot instantiate
    Vehicle v = new Car();
    v.start();   // Turn the key, engine runs
    v.fuelUp();  // Filling the tank
  }
}
Note: If a subclass forgets to implement an abstract method, the code will not compile. This is a feature, not a nuisance: it guarantees every concrete vehicle really does define how it starts.

Why hide the details?

The point of abstraction is to let callers work with a simple, stable idea while the messy implementation stays out of sight. Someone using a Vehicle only needs to know they can call start(). They do not need to understand ignition systems, electric motors, or anything else. This keeps code easier to read and lets you change the internals without breaking callers.

Sharing common logic in the abstract class

abstract class Payment {
  double amount;
  Payment(double amount) { this.amount = amount; }

  // each payment type completes this differently
  public abstract void process();

  // shared behavior lives here, written once
  public void logReceipt() {
    System.out.println("Paid " + amount);
  }
}

class CardPayment extends Payment {
  CardPayment(double amount) { super(amount); }

  @Override
  public void process() {
    System.out.println("Charging card: " + amount);
    logReceipt();
  }
}

public class Main {
  public static void main(String[] args) {
    Payment p = new CardPayment(49.99);
    p.process();
  }
}

Abstract class vs interface

Both abstract classes and interfaces let you define methods without bodies, so beginners often wonder which to use. The short answer: use an abstract class when subclasses share state or common code, and use an interface when you only need to define a capability that unrelated classes can adopt.

AspectAbstract classInterface
Instance fieldsYesOnly constants
ConstructorsYesNo
Multiple inheritanceOnly one parentA class can implement many
Best forShared state and codeA shared capability or contract
Note: Abstraction is one of the four pillars of object-oriented programming, alongside encapsulation, inheritance, and polymorphism. You will see the four mentioned together throughout your Java journey.

Exercise: Java Abstraction

What is the main purpose of abstraction in Java?