Course topics

By WebNest Studio Engineering Team

Java - Core Tutorial

Abstraction and Abstract Classes

Abstraction means exposing only the essential behavior of an object while hiding the internal implementation details. In Java, abstraction is achieved primarily through abstract classes and interfaces, both of which let you define "what" an object can do without necessarily specifying "how" every part of it works.

An abstract class is a class declared with the abstract keyword that cannot be instantiated on its own. It exists to be extended, providing a partial implementation that subclasses complete or override.

Why it matters

An abstract class lets you write the shared part of a family of classes once and force each subclass to supply the part that differs. It is the tool for "every employee is paid, but how the pay is calculated depends on the type". The compiler then guarantees that no subclass forgets to provide its piece.

Watch: Abstraction in Java - Complete Deep Dive | Abstract Class, Interface & Real Examples

A deep dive into abstraction in core Java, including how abstract classes and interfaces hide implementation details behind clear contracts, with practical examples.

Watch on YouTube

Declaring an Abstract Class

An abstract class can contain a mix of abstract methods (declared without a body, ending in a semicolon) and concrete methods (with a full implementation). It can also have constructors, fields, and static methods, even though it can never be instantiated directly with new.

  • An abstract class is declared with the abstract keyword before class.
  • It can have zero or more abstract methods — even zero is legal, though unusual.
  • It can have fully implemented (concrete) methods that subclasses inherit as-is.
  • You cannot write new AbstractClassName(); the compiler rejects it.

Extending an Abstract Class

A concrete (non-abstract) subclass must implement every abstract method it inherits, or the compiler forces it to also be declared abstract. This guarantees that by the time an object is actually created, every abstract method has a real implementation somewhere in the hierarchy.

Why Use Abstraction

Abstract classes let you share common code and fields across related classes while still forcing each subclass to supply its own specific behavior for the parts that must differ. This keeps a common contract in one place instead of duplicating it, and lets you write code against the abstract type so it works with any future subclass.

Example

An abstract class mixing a concrete method and an abstract method

Java
abstract class Shape {
    String name;

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

    // Concrete method — shared by every subclass
    void describe() {
        System.out.println(name + " has area " + area());
    }

    // Abstract method — each subclass must define this
    abstract double area();
}

class Circle extends Shape {
    double radius;

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

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

public class AbstractionDemo {
    public static void main(String[] args) {
        Shape s = new Circle(2.0);
        s.describe();
    }
}
Output
Circle has area 12.566370614359172

Common Mistakes

  • Trying to instantiate an abstract class directly with new — this always fails to compile.
  • Forgetting to implement even one inherited abstract method in a concrete subclass, which forces that subclass to also be declared abstract.
  • Assuming an abstract class cannot have a constructor — it can, and subclasses call it via super().
  • Marking a class abstract but never actually adding any abstract methods, then wondering why it "does nothing special."

Exercise

Complete the two subclasses of the abstract Employee. A full-time employee is paid a fixed salary; a contractor is paid hours multiplied by an hourly rate.

Expected output: Pay: 50000 then Pay: 30000

Java · starter code
abstract class Employee {
    abstract int pay();

    String describe() {
        return "Pay: " + pay();
    }
}

// TODO: class FullTime extends Employee, constructed with a salary
// TODO: class Contractor extends Employee, constructed with hours and a rate

public class PayrollDemo {
    public static void main(String[] args) {
        Employee[] staff = { new FullTime(50000), new Contractor(100, 300) };
        for (Employee employee : staff) {
            System.out.println(employee.describe());
        }
    }
}
Show hints
  • Each subclass must implement pay(), or it would have to be declared abstract too.
  • describe() is inherited as it is; it calls whichever pay() the object provides.
Show solution
Java · solution
abstract class Employee {
    abstract int pay();

    String describe() {
        return "Pay: " + pay();
    }
}

class FullTime extends Employee {
    private final int salary;

    FullTime(int salary) {
        this.salary = salary;
    }

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

class Contractor extends Employee {
    private final int hours;
    private final int rate;

    Contractor(int hours, int rate) {
        this.hours = hours;
        this.rate = rate;
    }

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

public class PayrollDemo {
    public static void main(String[] args) {
        Employee[] staff = { new FullTime(50000), new Contractor(100, 300) };
        for (Employee employee : staff) {
            System.out.println(employee.describe());
        }
    }
}

Quick quiz

1. Shape is an abstract class. What happens with new Shape()?

  • A. It creates an empty Shape
  • B. It returns null
  • C. It throws an exception at runtime
  • D. It does not compile
Show answer

D. An abstract class cannot be instantiated directly. You create objects of its concrete subclasses.

2. Can an abstract class have no abstract methods at all?

  • A. Yes; abstract only means it cannot be instantiated
  • B. No, it needs at least one
  • C. Only if it is also final
  • D. Only if it implements an interface
Show answer

A. A class may be declared abstract purely to prevent direct instantiation, even when every method has a body.

3. A concrete subclass does not implement one of the abstract methods it inherits. What happens?

  • A. The method returns a default value
  • B. It does not compile unless the subclass is also abstract
  • C. It throws at runtime when called
  • D. The method is removed
Show answer

B. Every abstract method must be implemented by the first concrete class in the hierarchy.

Interview questions

Can an abstract class have a constructor if it cannot be instantiated?

Show answer

Yes. The constructor is not called with new on the abstract class itself, but it runs whenever a subclass object is created, through super(...). It is used to initialise the fields that the abstract class declares.

Can an abstract method be private, static or final?

Show answer

No. An abstract method exists to be overridden in a subclass. A private method is not visible to subclasses, a final method cannot be overridden, and a static method is not overridden at all, so each combination contradicts the purpose and is rejected by the compiler.

Key Points to Remember

  • Abstract classes cannot be instantiated but can be extended.
  • They may contain both abstract methods (no body) and concrete methods (full implementation).
  • A concrete subclass must implement all inherited abstract methods.
  • Abstraction hides implementation details and exposes only the essential contract.

Practice in the playground

Write and run your own code for this topic, or start from the exercise or an example. Runs plain Java 17. Frameworks such as Spring, and databases, are not available here. Your code for each topic is kept in this browser.

Run the examples

Change an input, predict the result, then compare it with the output. Explain why the result changes.

WebNest Studio

Written by

WebNest Studio Engineering Team

Practical lessons from developers working with Java, Python, React, databases and production systems.

Led by Vansh Duggal, Founder, WebNest Studio · Full-stack & software engineering