Java Abstraction

Java abstraction means showing the important actions of a class while hiding the details of how those actions are done. In Java, one common way to create abstraction is with an abstract class.

An abstract class can describe what related classes must be able to do, while leaving some details for each subclass to provide.

Why Abstraction Matters

Abstraction helps you write code against a clear idea instead of a pile of details. For example, many shapes can have an area, but a rectangle and a square calculate that area differently.

With abstraction, the parent class can say, “every shape has an area,” and each specific shape can decide how to calculate it.

Abstract Classes And Methods

Use the abstract keyword before a class to make it abstract. An abstract class cannot be created directly with new. It is meant to be extended by other classes.

An abstract method has no method body. A concrete subclass must override it, unless that subclass is also abstract.

abstract class Shape {
    abstract int area();

    void printArea() {
        System.out.println("Area: " + area());
    }
}

class Rectangle extends Shape {
    private int width;
    private int height;

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

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

class Square extends Shape {
    private int side;

    Square(int side) {
        this.side = side;
    }

    @Override
    int area() {
        return side * side;
    }
}

public class Main {
    public static void main(String[] args) {
        Shape first = new Rectangle(4, 5);
        Shape second = new Square(6);

        first.printArea();
        second.printArea();
    }
}

Output:

Area: 20
Area: 36

The Shape class does not know how to calculate every possible area, so area() is abstract. The Rectangle and Square classes provide their own versions.

The printArea() method is not abstract. It has a body, so all subclasses can reuse it. When it calls area(), Java runs the overridden method from the actual object.

Abstract Classes Can Have Fields And Constructors

An abstract class can still have fields, constructors, and normal methods. The constructor is called when a subclass object is created, even though you cannot create the abstract class by itself.

abstract class Employee {
    private String name;

    Employee(String name) {
        this.name = name;
    }

    abstract int monthlyPay();

    void printPay() {
        System.out.println(name + " earns " + monthlyPay());
    }
}

class SalariedEmployee extends Employee {
    private int salary;

    SalariedEmployee(String name, int salary) {
        super(name);
        this.salary = salary;
    }

    @Override
    int monthlyPay() {
        return salary;
    }
}

class HourlyEmployee extends Employee {
    private int hours;
    private int rate;

    HourlyEmployee(String name, int hours, int rate) {
        super(name);
        this.hours = hours;
        this.rate = rate;
    }

    @Override
    int monthlyPay() {
        return hours * rate;
    }
}

public class Main {
    public static void main(String[] args) {
        Employee first = new SalariedEmployee("Maya", 5000);
        Employee second = new HourlyEmployee("Leo", 120, 30);

        first.printPay();
        second.printPay();
    }
}

Output:

Maya earns 5000
Leo earns 3600

The Employee constructor stores the shared name field. Each subclass decides how monthlyPay() should work, but both subclasses reuse printPay().

Abstract Vs Concrete

A concrete class is a regular class that can be instantiated. A class with any abstract method must be declared abstract, because Java would not know how to run that missing method body.

  • abstract class Shape describes shared behavior but cannot be created directly.
  • class Rectangle extends Shape is concrete because it implements area().
  • A variable can still use the abstract type, such as Shape first, to refer to a concrete subclass object.

When To Use Abstraction

Use an abstract class when related classes share common code, but some behavior must be supplied by each subclass. It is useful when you want a common parent type and reusable fields or methods.

If you only need to describe methods that many unrelated classes can implement, Java interfaces are often a better fit. The next lesson covers interfaces in more detail.

Common Mistakes

  • Trying to create an abstract class directly with new Shape().
  • Forgetting to override every abstract method in a concrete subclass.
  • Putting a method body on an abstract method.
  • Using an abstract class when there is no shared code or clear parent-child relationship.

Takeaway: abstraction lets a parent class define a common idea while subclasses provide the specific details.