Abstraction in Swift


In Swift, abstraction is a core concept of Object-Oriented Programming (OOP) that focuses on hiding complex implementation details and exposing only the essential features of an object. It helps in reducing programming complexity and effort by showing only relevant information to the user and hiding unnecessary details.

Abstraction allows developers to design blueprints or templates (using classes and protocols) without worrying about the specific implementation. In Swift, abstraction is achieved through classes, protocols, and methods that define behaviors but hide internal workings.

Key Points to Remember

  • Abstraction helps hide internal implementation details and exposes only necessary functionalities.
  • In Swift, abstraction is achieved using protocols, abstract classes (base classes), and methods without implementations.
  • Protocols define a blueprint of methods and properties, but do not provide the implementation.
  • Subclasses or conforming types provide specific implementations for abstract behaviors.
  • Abstraction enhances security, flexibility, and maintainability of code.

Syntax

protocol ProtocolName {
     func methodName()
}

class ClassName: ProtocolName {
     func methodName() {
         // Implementation of the method
    }
}

Example 1: Abstraction Using Protocols

Let's demonstrate abstraction by defining a protocol and implementing it in multiple classes.

import Foundation

protocol Vehicle {
     func startEngine()
     func stopEngine()
}

class Car: Vehicle {
     func startEngine() {
         print("Car engine started")
    }

     func stopEngine() {
         print("Car engine stopped")
    }
}

class Bike: Vehicle {
     func startEngine() {
         print("Bike engine started")
    }

     func stopEngine() {
         print("Bike engine stopped")
    }
}

let car = Car()
car.startEngine()
car.stopEngine()

let bike = Bike()
bike.startEngine()
bike.stopEngine()

Output

Car engine started
Car engine stopped
Bike engine started
Bike engine stopped

Example 2: Abstraction with Base Class and Method Overriding

Abstraction can also be achieved using a base class with methods that are overridden in subclasses.

import Foundation

class Animal {
     func sound() {
         // Abstract method: should be overridden
    }
}

class Dog: Animal {
     override func sound() {
         print("Dog barks")
    }
}

class Cat: Animal {
     override func sound() {
         print("Cat meows")
    }
}

let animals: [Animal] = [Dog(), Cat()]

for animal in animals {
    animal.sound()
}

Output

Dog barks
Cat meows

Example 3: Real-world Example of Abstraction Using Protocols and Structs

Here is a real-world example using a protocol for a payment system.

import Foundation

protocol PaymentMethod {
     func pay(amount: Double)
}

struct CreditCard: PaymentMethod {
     func pay(amount: Double) {
         print("Paid \(amount) using Credit Card")
    }
}

struct PayPal: PaymentMethod {
     func pay(amount: Double) {
         print("Paid \(amount) using PayPal")
    }
}

func makePayment(method: PaymentMethod, amount: Double) {
    method.pay(amount: amount)
}

let creditCard = CreditCard()
let payPal = PayPal()

makePayment(method: creditCard, amount: 100.0)
makePayment(method: payPal, amount: 150.0)

Output

Paid 100.0 using Credit Card
Paid 150.0 using PayPal