โ† Back to OOP Concepts
๐ŸŽญ
Pillars

Abstraction

Hides complex implementation details behind a simple, well-defined interface, exposing only what the caller needs.

The Problem

Without abstraction, callers must understand and depend on every implementation detail of a system, making code harder to use, change, and test โ€” and impossible to swap implementations.

How It Works

  • โ€บAbstract classes/protocols/interfaces describe *what* an object does, not *how*
  • โ€บConcrete implementations fill in the "how" behind the abstraction
  • โ€บCallers program against the abstraction, enabling swappable implementations
  • โ€บReduces cognitive load by exposing only relevant operations

When to Use

โœ“Designing public APIs or libraries
โœ“Supporting multiple implementations behind one interface (e.g., payment providers)
โœ“Isolating volatile subsystems behind a stable boundary

Real-World Examples

๐ŸŽ
iOS

Protocols like Codable and Equatable hide conformance details from callers

๐Ÿค–
Android

Repository interfaces hide whether data comes from Room or a network call

๐ŸŒ
Web

A Storage interface abstracting over localStorage, sessionStorage, or IndexedDB

Code Examples

Swift
protocol PaymentProcessor {
    func pay(amount: Double)
}

class CreditCardProcessor: PaymentProcessor {
    func pay(amount: Double) {
        print("Charging $\(amount) to credit card")
    }
}

class PayPalProcessor: PaymentProcessor {
    func pay(amount: Double) {
        print("Sending $\(amount) via PayPal")
    }
}

func checkout(amount: Double, processor: PaymentProcessor) {
    processor.pay(amount: amount)
}

checkout(amount: 49.99, processor: PayPalProcessor())