Protocols

Protocols in Swift define a blueprint of methods, properties, and other requirements that a conforming type must implement. They are a cornerstone of protocol-oriented programming, which Swift emphasizes over traditional inheritance.

Syntax

protocol Vehicle {
    var numberOfWheels: Int { get }
    func drive()
}

Conforming to a Protocol

A class, struct, or enum can conform to a protocol by implementing all its requirements.

struct Car: Vehicle {
    var numberOfWheels: Int = 4

    func drive() {
        print("Driving a car")
    }
}

let car = Car()
print(car.numberOfWheels)  // Output: 4
car.drive()                // Output: Driving a car

Protocol Inheritance

Protocols can specify methods that conforming types must implement.

protocol Person {
    var name: String { get }
}

protocol Employee: Person {
    var employeeID: String { get }
}

struct Developer: Employee {
    var name: String
    var employeeID: String
}

let dev = Developer(name: "Bishal", employeeID: "123")
print(dev.name)         // Output: Bishal
print(dev.employeeID)   // Output: 123

Protocol Composition

A protocol can inherit from one or more protocols.

protocol Flyable {
    func fly()
}

protocol Swimmable {
    func swim()
}

struct Duck: Flyable, Swimmable {
    func fly() {
        print("Duck is flying")
    }

    func swim() {
        print("Duck is swimming")
    }
}

let duck: Flyable & Swimmable = Duck()
duck.fly()
duck.swim()

Protocols with Default Implementation

Using extensions, protocols can provide default implementations for methods and computed properties.

protocol Greeting {
    func sayHello()
}

extension Greeting {
    func sayHello() {
        print("Hello!")
    }
}

struct Person: Greeting {}
let person = Person()
person.sayHello()  // Output: Hello!

Protocols with Associated Types

Protocols can use associated types as placeholders for a type that is defined when the protocol is adopted. (Will discuss in next Generics topic)

protocol Container {
    associatedtype Item
    func add(item: Item)
    func getItem() -> Item
}

struct Box: Container {
    var item: String

    func add(item: String) {
        print("Adding \(item) to the box")
    }

    func getItem() -> String {
        return item
    }
}

let box = Box(item: "Book")
box.add(item: "Notebook")
print(box.getItem())  // Output: Book

Leave a Reply

Your email address will not be published. Required fields are marked *