Swift Protocols

In Swift, a protocol defines a blueprint of methods or properties that can then be adopted by classes (or any other types).

We use the protocol keyword to define a protocol. For example,

protocol Greet {

  // blueprint of a property 
  var name: String { get }


  // blueprint of a method 
  func message() 
}    

Here,

  • Greet - name of the protocol
  • name - a gettable property
  • message() - method definition without any implementation

Notes:

  • The protocol just holds the method or properties definition, not their actual body.
  • The protocol must specify whether the property will be gettable or gettable and settable.

Conform Class To Swift Protocol

In Swift, to use a protocol, other classes must conform to it. After we conform a class to the protocol, we must provide an actual implementation of the method.

Here's how to conform a class to the protocol,

// conform class to Greet protocol
class Employee: Greet {

  // implementation of property
  var name = "Perry"

  // implementation of method
  func message() {
    print("Good Morning!")
  }
}

Here, we have conformed the Employee class to the Greet protocol. So, we must provide an implementation of the name property and the message() method.


Example 1: Swift Protocol

protocol Greet {
  
  // blueprint of property
  var name: String { get }

  // blueprint of a method 
  func message() 
} 

// conform class to Greet protocol
class Employee: Greet {

  // implementation of property
  var name = "Perry"

  // implementation of method
  func message() {
    print("Good Morning", name)
  }
}

var employee1 = Employee()
employee1.message()

Output

Good Morning Perry

In the above example, we have created a protocol named Greet. The protocol contains a blueprint of the name property and the message() method.

Here, the Employee class conforms to Greet and provides the actual implementation of name and message().


Example 2: Swift Protocol To Calculate Area

protocol Polygon {

  func getArea(length: Int, breadth: Int)
}

// conform the Polygon protocol
class Rectangle: Polygon {

  // implementation of method
  func getArea(length: Int, breadth: Int) {
    print("Area of the rectangle:", length * breadth)
  }
}

// create an object
var r1 = Rectangle()

r1.getArea(length:5, breadth: 6)

Output

Area of the rectangle: 30

In the above example, we have created a protocol named Polygon. The protocol contains a blueprint of the getArea() method with two parameters: length and breadth.

Here, the Rectangle class conforms to Polygon and provides the actual implementation of the getArea() method.

func getArea(length: Int, breadth: Int) {
  print("Area of the rectangle:", length * breadth)
}

Conforming Multiple Protocols

In Swift, a class can also conform to multiple protocols. For example,

protocol Sum {
  ...
}

protocol Multiplication {
  ...
}

class Calculate: Sum, Multiplication {
  ...
}

Here, the class named Calculate conforms to the Sum and Multiplication protocols.


Example 3: Conforming Multiple Protocols

// create Sum protocol
protocol Sum {

  func addition()
}

// create Multiplication protocol
protocol Multiplication {

  func product()
}

// conform class to two protocols
class Calculate: Sum, Multiplication {

  var num1 = 0
  var num2 = 0

  func addition () {
    let result1 = num1 + num2
    print("Sum:", result1)
  }

  func product () {
    let result2 = num1 * num2
    print("Product:", result2)
  }
                   
}

// create an object
var calc1 = Calculate()

// assign values to properties
calc1.num1 = 5
calc1.num2 = 10

// access methods
calc1.addition()
calc1.product()

Output

Sum: 15
Product: 50
 

In the above example, we have created two protocols: Sum and Multiplication. Also, we have created a class named Calculate that conforms to these two protocols.

We have created a blueprint of methods named addition() and product() inside the Sum and Multiplication protocols respectively.

protocol Sum {

  func addition()
}

protocol Multiplication {

  func product()
}

Since Calculate conforms to Sum and Multiplication, we have provided an actual implementation of addition() and product() inside the class.

Finally, we have accessed these methods using the calc1 object of the class.

// access methods
calc1.addition()
calc1.product()

Swift Protocol Inheritance

Similar to classes, protocols can inherit other protocols. For example,

protocol Car {
  ...
}

protocol Brand: Car {
  ...
}

Here, the Brand protocol inherits the Car protocol. Now, if any class implements Brand, it should provide implementations for all properties of both Car and Brand.


Example 4: Swift Protocol Inheritance

protocol Car {
  var colorOptions: Int { get }
}

// inherit Car protocol
protocol Brand: Car {
  var name: String { get }
}

class Mercedes: Brand {

  // must implement properties of both protocols 
  var name: String = ""
  var colorOptions: Int = 0
}

var car1 = Mercedes()
car1.name = "Mercedes AMG"
car1.colorOptions = 4

print("Name:", car1.name)
print("Color Options:", car1.colorOptions)

Output

Name: Mercedes AMG
Color Options: 4
 

In the above example, the Brand protocol inherits the Car protocol.

Here, the Mercedes class only conforms to Brand. But since Brand inherits Car, we need to implement all the properties of both Car and Brand.

Note: A protocol can inherit multiple protocols. For example,

protocol A {
  ...
}
protocol B {
  ... 
}

protocol C: A, B {
  ...
}

Protocol Extensions

In Swift, we can extend protocols using the extension keyword. For example,

// protocol definition
protocol Brake {
  func applyBrake()
}

// define class that conforms Brake
class Car: Brake {
  var speed: Int = 0

  func applyBrake() {
    print("Brake Applied")
  }
}

// extend protocol
extension Brake {
  func stop() {
    print("Engine Stopped")
  }
}

let car1 = Car()
car1.speed = 61
print("Speed:", car1.speed)

car1.applyBrake()

// access extended protocol
car1.stop()

Output

Speed: 61
Brake Applied
Engine Stopped

In the above example, we have created the protocol Brake that defines the function applyBrake().

We have extended the Brake protocol and defined the stop() function inside it.

// extend protocol
extension Brake {
  func stop() {
    print("Engine Stopped")
  }
}

We can access the extended protocol using the car1 object.

// access extended protocol
car1.stop()
Did you find this article helpful?