What Is Abstraction?

Abstraction means hiding the complex details of how something works and showing only the important parts needed by the user.
It is like driving a car: you do not need to know how the engine, gearbox, or fuel system works internally; you only interact with the steering wheel, pedals, and gear stick.

In object‑oriented programming and low-level design:

  • Abstraction is about deciding what information and behavior should be visible to the outside world.

  • Details that are not relevant to the caller are kept hidden inside the class or module.

Abstraction is not the same as encapsulation:

  • Encapsulation is about hiding data and controlling access (using private fields and public methods).

  • Abstraction is about hiding complexity and simplifying the interface (what you choose to expose and what you leave out).

In LLD, abstraction helps you design clean, easy‑to‑use boundaries between components.

Why Abstraction Matters in LLD

In large systems and LLD interview problems, abstraction has several key benefits.

  • Simplifies usage

    • A user of a class or service does not need to know every internal detail; only the relevant methods and concepts.

    • This makes API design easier and less intimidating.

  • Reduces coupling

    • When the internal details are hidden, the rest of the system depends only on the abstract behavior.

    • You can change the internals without breaking code that uses the abstraction.

  • Implements the “black‑box” idea

    • Each class or module becomes a black box: it has a clear input/output contract.

    • You can think in terms of “what it does” instead of “how it does it.”

  • Supports maintainability

    • If you always go through a clean interface, you can safely refactor or replace the implementation.

For interviews, using abstraction well shows that you can think in terms of boundaries and contracts, not just raw code.

Abstraction vs Encapsulation

To avoid confusion, compare them directly:

  • Encapsulation

    • Focus: protecting data and controlling how it is accessed.

    • Mechanism: private fields, public methods, getters/setters.

    • Example: a BankAccount class keeps its balance private and only lets you change it through deposit() and withdraw().

  • Abstraction

    • Focus: simplifying the external view by hiding irrelevant details.

    • Mechanism: choosing which methods and types to expose, using interfaces and abstract classes.

    • Example: a PaymentService exposes a simple pay(amount) method; the user does not need to know whether it uses card, UPI, or wallet internally.

In practice, you often use both together:

  • Encapsulation protects the internal state.

  • Abstraction hides the implementation complexity behind a clean interface.

How Abstraction Shows Up in Classes and Methods

Even without special keywords, you can see abstraction in everyday class design.

1. Choosing What to Expose

A class should expose only the methods that are needed by its callers.

Example Calculator class:

  • preprocess is an internal helper; the user never calls it.

  • add, subtract, and getLastResult are the abstract interface the user sees.

  • The caller does not know about lastResult or preprocess unless they look at the implementation.

This is an abstraction: only the essential operations are exposed.

2. Hiding Implementation Details

Another example: a PaymentProcessor that hides the payment gateway.

A user of PaymentProcessor only cares about:

They do not know (or need to know) which service it uses or what HTTP calls it makes.

Abstraction Using Abstract Classes and Interfaces

In C++, abstraction is often expressed through abstract classes and interface‑like classes defined with pure virtual functions.

Abstract Class for Abstraction

A class that cannot be instantiated and defines only the “shape” of behavior is an abstraction.

Here: It 

  • Shape is an abstract class; it cannot be instantiated directly.

  • It defines an abstraction: “any shape has an area and a perimeter.”

  • Specific shapes (Circle, Rectangle, etc.) implement the details.

Concrete implementations:

Using abstraction:

Here, printShapeInfo depends on the abstract Shape class, not on concrete Circle or Rectangle.

This is abstraction in action: the function knows only that there is an area() and a perimeter(), not how they are computed.

Abstraction in LLD‑Style Design Problems

In LLD interview‑style problems, abstraction helps you:

  • Model services

    • A NotificationService Abstraction can have methods like sendWelcome(), sendOrderUpdate(), and sendAlert() without exposing the details of email, SMS, or push.

  • Model payment

    • A PaymentGateway abstraction lets your OrderService call charge() without caring which provider is used.

  • Model data access

    • A UserRepository abstraction provides findById, save, etc., without exposing whether data comes from memory, file, or database.

Example sketch:

  • UserService depends on the abstract UserRepository.

  • It does not know which concrete implementation (InMemoryUserRepository or DatabaseUserRepository) is used.

  • This is abstraction: the what is clear, the how is hidden.

How to Think About Abstraction When Designing

When you design classes in LLD, ask yourself:

  • What is the core responsibility of this class or service?

    • What should it be able to do?

  • What details are not relevant to the caller?

    • Can they be pushed into private methods, or into a separate internal class?

  • Can I express this as a clean interface or abstract class?

    • For example, can I define a Notifier, PaymentProcessor, or Calculator That hides the details?

A good rule of thumb:

  • Expose: methods that represent meaningful operations in the problem domain (e.g., login, confirmOrder, sendNotification).

  • Hide: helper functions, internal data structures, and implementation‑specific choices that are not part of the abstract idea.

Common Mistakes with Abstraction

Some typical mistakes:

  • Over‑abstracting

    • Creating interfaces and abstract classes when there is only one implementation and no clear need for more.

    • This adds unnecessary complexity.

  • Under‑abstracting

    • Exposing too many internal details directly to the caller.

    • This makes the design hard to change later.

  • Mixing abstraction and implementation in one class

    • A class that combines high‑level logic and low‑level details becomes hard to test and understand.

    • Better to separate concerns and abstract away the details.

  • Abstracting the wrong level

    • For example, a class that abstracts a tiny, trivial helper, when it should have been inlined.

    • Think about what the user of the class really needs to see.

Being aware of these helps you use abstraction judiciously and effectively.

Summary

Abstraction is the idea of hiding complex details and exposing only the essential parts of a system.
It lets you simplify the interface of a class or service so that callers interact with it at the right level of detail.

You now understand:

  • What abstraction is and how it differs from encapsulation.

  • How to apply abstraction in regular classes by hiding internal helpers and exposing only meaningful methods.

  • How to use abstract classes and interface‑like types in C++ to define behavior without implementation.

  • How abstraction appears in LLD problems like payment, notification, and data‑access services.

  • Common mistakes to avoid when deciding what to abstract and what to expose.