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