Protocols

  1. Protocols define a set of required properties and methods that a type must implement.
  2. Protocols act as contracts, ensuring that conforming types adhere to specific functionality.
  3. Protocols don't provide implementations; they serve as blueprints for defining requirements.
  4. Types can conform to protocols by implementing all required properties and methods.
  5. Protocol conformance allows treating instances of different types as a shared type.
  6. Protocols can include properties that specify read-only or read-write requirements.
  7. Protocol arrays enable working with collections of objects conforming to the same protocol.
  8. Functions can accept protocols as parameters and return protocols as return types.
  9. A type can conform to multiple protocols by listing them separated by commas:.
protocol Vehicle {
		var name: String { get }
    var currentPassengers: Int { get set }
    func estimateTime(for distance: Int) -> Int
    func travel(distance: Int)
}

struct Car: Vehicle {
		let name = "Car"
		var currentPassengers = 1
		
    func estimateTime(for distance: Int) -> Int {
        distance / 50
    }

    func travel(distance: Int) {
        print("I'm driving \\(distance)km.")
    }

    func openSunroof() {
        print("It's a nice day!")
    }
}

struct Bicycle: Vehicle {
		let name = "Bicycle"
		var currentPassengers = 1
    func estimateTime(for distance: Int) -> Int {
        distance / 10
    }

    func travel(distance: Int) {
        print("I'm cycling \\(distance)km.")
    }
}

func commute(distance: Int, using vehicle: Vehicle) {
    if vehicle.estimateTime(for: distance) > 100 {
        print("That's too slow! I'll try a different vehicle.")
    } else {
        vehicle.travel(distance: distance)
    }
}

let car = Car()
commute(distance: 100, using: car) // I'm driving 100km.
let bike = Bicycle()
commute(distance: 50, using: bike) // I'm cycling 50km.

func getTravelEstimates(using vehicles: [Vehicle], distance: Int) {
    for vehicle in vehicles {
        let estimate = vehicle.estimateTime(for: distance)
        print("\\(vehicle.name): \\(estimate) hours to travel \\(distance)km")
    }
}

getTravelEstimates(using: [car, bike], distance: 150)
// Car: 3 hours to travel 150km
// Bicycle: 15 hours to travel 150km

Sample code

protocol BasketballPlayer {
    var playerNumber: Int { get }
    func dribble()
    func shoot()
}

struct NBAPlayer: BasketballPlayer {
    let playerNumber: Int
    
    func dribble() {
        print("Player #\\(playerNumber) is dribbling the basketball.")
    }
    
    func shoot() {
        print("Player #\\(playerNumber) is shooting the basketball.")
    }
}

var player = NBAPlayer(playerNumber: 23)
player.dribble() // Player 23 is dribbling the basketball.
player.shoot() // Player 23 is shooting the basketball.