UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

When should we use protocol inheritance?

Paul Hudson    @twostraws   

Updated for Xcode 15

Swift lets us build new protocol based on existing protocols, much like the way it lets us build new classes based on existing classes.

One common reason for using protocol inheritance is to combine functionality for common work. For example:

  • All products have a price and a weight
  • All computers have a CPU, plus how much memory they have and how much storage
  • All laptops have a screen size

You could absolutely define a Computer protocol like this:

protocol Computer {
    var price: Double { get set }
    var weight: Int { get set }
    var cpu: String { get set }
    var memory: Int { get set }
    var storage: Int { get set }
}

Then define a Laptop protocol like this:

protocol Laptop {
    var price: Double { get set }
    var weight: Int { get set }
    var cpu: String { get set }
    var memory: Int { get set }
    var storage: Int { get set }
    var screenSize: Int { get set }
}

But do you see how much duplication we already have? Now imagine working with phones and tablets – more protocols, and more duplication.

It’s much simpler and more flexible if we break our protocols up into smaller parts, then reassemble them like Lego bricks.

So, we could start by defining what a product looks like:

protocol Product {
    var price: Double { get set }
    var weight: Int { get set }
}

We could then define what a computer looks like, by basing it on a Product then adding some extras:

protocol Computer: Product {
    var cpu: String { get set }
    var memory: Int { get set }
    var storage: Int { get set }
}

Now we can define what a Laptop looks like, by basing it on a Computer (and therefore also a Product), and adding another property:

protocol Laptop: Computer {
    var screenSize: Int { get set }
}

As you can see, using protocol inheritance in this way lets us share definitions and reduce duplication, which is a great way to build up functionality piece by piece.

The second common reason for using protocol inheritance is to add extra restrictions when they make sense. For example, Swift has a protocol called Equatable, which means “this thing can be checked for equality against other instances of the same type,” and it’s what makes 5 == 6 return false. Swift also has a protocol called Comparable, which means “this type can be checked to see whether it is less than or greater than another instance of the same type,” and it’s what makes "Hello" < "World" return true.

Think about it: if we can know whether an object is less than or greater than some other object, then we must also be able to know when it is the same as the other object. That is, if number X is not less than number Y, and is also not greater than number Y, then X and Y must be equal.

Rather than copy all the functionality of Equatable into Comparable, Swift just uses protocol inheritance so that Comparable inherits from Equatable.

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

BUY OUR BOOKS
Buy Pro Swift Buy Pro SwiftUI Buy Swift Design Patterns Buy Testing Swift Buy Hacking with iOS Buy Swift Coding Challenges Buy Swift on Sundays Volume One Buy Server-Side Swift Buy Advanced iOS Volume One Buy Advanced iOS Volume Two Buy Advanced iOS Volume Three Buy Hacking with watchOS Buy Hacking with tvOS Buy Hacking with macOS Buy Dive Into SpriteKit Buy Swift in Sixty Seconds Buy Objective-C for Swift Developers Buy Beyond Code

Was this page useful? Let us know!

Average rating: 4.7/5

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.