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()