JavaOOPbeginner
Updated:

Abstraction in Java: Abstract Classes and Interfaces

5 min read

Abstraction hides how and exposes what. Learn abstract classes, interfaces, default methods, and the decision rule for choosing between them in real designs and interviews.

TL;DR – Quick Answer

Abstraction in Java means exposing what an object does while hiding how it does it. Java provides two tools for this: abstract classes, which can mix implemented methods with abstract (bodyless) ones and hold state, and interfaces, which define a pure contract that any class can implement. Neither can be instantiated directly.

On This Page

When you call list.sort(), do you know which sorting algorithm runs underneath? You do not need to — and that is abstraction working as intended. You program against a promise ("this will sort") while the implementation stays hidden and free to change.

Java gives you two constructs to build such promises: abstract classes and interfaces. Freshers routinely learn the syntax of both but freeze when asked "which one would you choose, and why?" This tutorial fixes that, building on what you know from inheritance and polymorphism.

What abstraction really means

Abstraction is the practice of exposing what an operation does while hiding how it does it. The caller sees a minimal, stable surface; the messy details live behind it.

Two benefits follow:

  1. Swap-ability. Code written against PaymentGateway works with any implementation — today's and next year's.
  2. Enforced contracts. The compiler guarantees every concrete subclass provides the promised methods, so a half-finished implementation cannot even compile.

Do not confuse this with encapsulation, which hides data behind methods. Abstraction hides implementation behind contracts. Interviewers ask for this distinction constantly.

Abstract classes: partial implementations

An abstract class is declared with the abstract keyword and cannot be instantiated. It may contain abstract methods (signature only, no body) that subclasses must implement, alongside normal fields, constructors, and fully implemented methods.

abstract class Shape {
    private final String name;

    Shape(String name) {          // yes, abstract classes have constructors
        this.name = name;
    }

    abstract double area();       // no body: every subclass MUST provide one

    void describe() {             // concrete method: inherited as-is
        System.out.printf("%s has area %.2f%n", name, area());
    }
}

class Circle extends Shape {
    private final double radius;

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

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

class Rectangle extends Shape {
    private final double w, h;

    Rectangle(double w, double h) {
        super("Rectangle");
        this.w = w;
        this.h = h;
    }

    @Override
    double area() {
        return w * h;
    }
}

public class ShapeDemo {
    public static void main(String[] args) {
        Shape[] shapes = { new Circle(7), new Rectangle(4, 5) };
        for (Shape s : shapes) {
            s.describe();
        }
    }
}

What to notice: describe() is written once in the abstract class, yet prints correct output for both shapes because it calls the abstract area() — which dispatches to each subclass at runtime. Writing the common workflow in the parent and deferring one step to children is the template method pattern, and abstract classes exist largely for it.

Key rules:

  • A class with even one abstract method must itself be declared abstract.
  • An abstract class may have zero abstract methods (used purely to block instantiation).
  • Abstract classes can have constructors, fields of any kind, and any access modifiers.
  • A subclass that does not implement every inherited abstract method must be abstract too.

Common mistake: A common mistake beginners make is writing new Shape("Generic") and expecting a compile-time warning only. It is a hard compile error — abstract types can never be instantiated, though anonymous subclasses (new Shape("x") { ... }) are legal because they supply the missing bodies on the spot.

Interfaces: pure contracts

An interface declares capabilities with no state. A class implements it and must supply every abstract method. Since a class can implement many interfaces, this is Java's answer to multiple inheritance.

interface PaymentGateway {
    boolean pay(double amount);            // implicitly public abstract

    default String currency() {            // Java 8+: has a body
        return "INR";
    }
}

interface Refundable {
    void refund(String txnId, double amount);
}

class UpiGateway implements PaymentGateway, Refundable {
    @Override
    public boolean pay(double amount) {
        System.out.println("UPI payment of " + amount + " " + currency());
        return true;
    }

    @Override
    public void refund(String txnId, double amount) {
        System.out.println("Refunding " + amount + " for " + txnId);
    }
}

public class GatewayDemo {
    public static void main(String[] args) {
        PaymentGateway gw = new UpiGateway();   // interface reference
        gw.pay(1499.0);
        ((Refundable) gw).refund("TXN-1042", 1499.0);
    }
}

What to notice: UpiGateway picks up two unrelated contracts at once — something no class hierarchy allows. Also note the methods are public in the implementation: interface methods are implicitly public abstract, and you cannot narrow access when implementing.

Interface member rules worth memorizing:

  • Fields are implicitly public static final — constants only, no instance state.
  • Java 8 added default and static methods with bodies; Java 9 added private methods.
  • An interface can extend multiple interfaces.

Interview note: If two interfaces give a class conflicting default methods with the same signature, the code will not compile until the class overrides that method itself. Inside the override you can pick a side with InterfaceName.super.method(). This exact scenario is a staple senior-round question — see more on our Java OOP interview questions page.

Abstract class vs interface: the decision table

Dimension Abstract class Interface
Instance fields (state) Yes No (constants only)
Constructors Yes No
Method bodies Any method Only default, static, private
Access modifiers on members All four levels Essentially public
How many can one class take Extend one Implement many
Relationship it models "is-a, sharing code and state" "can-do capability"
Typical example Shape, HttpServlet Comparable, Runnable, List

The practical decision rule we teach: start with an interface. Reach for an abstract class only when implementations must share fields or common constructor logic. You can always add an abstract skeleton class under an interface later — the JDK itself does this with ListAbstractListArrayList, a pattern you will meet again in the Collections Framework.

Achieving 100% abstraction — and why the phrase is dated

Older textbooks say "interfaces give 100% abstraction, abstract classes 0–100%." Since Java 8 default methods, that line is no longer strictly true — an interface can now carry implementation. If an interviewer uses the phrase, agree with the historical intent (pre-Java-8 interfaces had no bodies) and then mention default methods. It shows your knowledge is current, not memorized from a 2012 PDF.

Pro tip: Default methods exist so the JDK could add methods like List.sort() and Collection.stream() to interfaces without breaking millions of existing implementing classes. Frame your answer around interface evolution and you will sound like someone who understands why the feature exists, not just its syntax.

Abstraction in real projects

Where you will actually use this in your first job:

  • Service layers: controllers depend on a UserService interface; the implementation can be swapped or mocked in tests.
  • JDBC: you code against Connection, Statement, ResultSet — all interfaces; each database vendor ships the hidden implementations.
  • Collections: you declare Map<String, Integer> and choose HashMap or TreeMap at one single point.

Abstraction is why the switch costs one line instead of a refactor.

Checklist before your next interview

  1. Define abstraction in one sentence without the word "hide" appearing twice.
  2. Write an abstract class with a constructor and explain when that constructor runs.
  3. List what interface fields and methods are implicitly.
  4. Resolve a default-method conflict with InterfaceName.super.
  5. Give the decision rule: interface first, abstract class for shared state.

We drill these with live design exercises in the OOP module of our Java Full Stack course — the same hierarchy questions asked at Hyderabad service and product companies.

Frequently Asked Questions

What is abstraction in Java with a real-time example?
Abstraction is exposing only the essential operations and hiding the implementation details. A payment app shows you a pay() button; whether the money moves via UPI, card rails, or net banking is hidden behind that single operation. In code, you define pay() in an interface and let UpiPayment or CardPayment supply the hidden details.
Can an abstract class have a constructor in Java?
Yes. You can never call it with new, but subclass constructors invoke it through super() to initialize the fields the abstract class declares. This is a favorite interview question precisely because it sounds contradictory until you remember constructor chaining.
Can we create an object of an interface or abstract class?
Not directly - new Shape() fails to compile if Shape is abstract. But references of these types are used everywhere: an interface or abstract class reference can point to any concrete subclass object, which is exactly how runtime polymorphism works. Anonymous classes and lambdas also provide on-the-spot implementations.
What is the difference between abstraction and encapsulation?
Abstraction hides implementation complexity at the design level - callers see a contract, not the working. Encapsulation hides data at the implementation level - fields are private and reached only through methods. A shorthand that works in interviews: abstraction hides the how, encapsulation hides the what (the data).
When should I use an abstract class instead of an interface?
Use an abstract class when subclasses share state (fields) or common constructor logic, or when you want non-public helper methods in the base type. Use an interface when you are defining a capability that unrelated classes can adopt, or when a class needs to pick up multiple contracts, since Java allows implementing many interfaces but extending only one class.
Can an interface have method implementations after Java 8?
Yes. Since Java 8, interfaces can declare default methods (with a body, inherited by implementers) and static methods. Java 9 added private methods for sharing code between defaults. Interfaces still cannot hold instance fields, so they remain stateless contracts.

Want to Build Your Career in Java Full Stack with AI?

Join CodeBegun and train with working industry engineers — Explore the Program

Apply for Demo Class →
Siva Prasad Galaba
Founder, CodeBegun · Staff Engineer

Founder of CodeBegun. 15+ years building Java systems at companies like Crunchyroll. Teaches Java, Spring Boot and system design the way the industry actually works, and mentors students through projects, mock interviews and placement preparation.

Technically reviewed by CodeBegun Technical TeamLast reviewed 14 July 2026 LinkedIn
Chat with us