Introduction 2

Comparing Protocols to Inheritance

If you really squint, the two approaches are fairly similar. They both allow you to define a blueprint for your types, such as properties and functions. However, the similarities end there. Protocols define the API for types to make it possible to interact with them without caring about the type. Inheritance defines the behavior of types as well as the API.

With inheritance, it’s possible to create an instance of the superclass that doesn’t make any sense. For example, you could write:

let vehicle = VehicleType()
vehicle.move(direction: .forward, duration: 15, speed: 30)
print(vehicle.showDetails())

In this example, you create an instance of VehicleType. But what does that mean? It doesn’t make sense to have a generic vehicle you can instantiate and pass around as a concrete type. Protocols make much more sense in this case.

On the other hand, with protocols, every implementor has to implement all the variables and all the functions, even if they’re the same. This can lead to duplicated code. There are a couple of other disadvantages to superclasses:

  • You can only inherit from one superclass. If you want to inherit behavior from two unrelated superclasses — you can’t. It isn’t possible. With protocols, you can conform to as many as you like.
  • You have no control over how your superclasses behave. They may change the values of properties that you rely on or perform additional logic that conflicts with your own. Remember, protocols only define the API of the types — the implementation is entirely up to you.

These disadvantages are why Swift favors protocols over inheritance (such as in SwiftUI).

Protocols are very useful for testing your code in this sense. You can define a protocol to retrieve your users from an API. In your tests, you can use a different implementation that returns hardcoded users. With inheritance, you’d need to be careful to ensure that your test subclass doesn’t make network requests, for instance.

Note: In Kotlin, you can create abstract classes. These classes cannot be instantiated; you can only use them by subclassing them. In Swift, you can use protocol extensions to provide a default implementation for a function. You’ll see this in a later lesson.

Protocol-Orientated Programming

Now that you understand the basics of protocols, you can start to learn about how to use them in your code. Protocol-Orientated Programming is a technique where you move different parts of your code to be called via a protocol. This could be a third-party dependency, a database, an API or even different modules for your app.

Using protocols to call different areas of your code provides a number of benefits:

  1. Writing tests for your code is easier. If you’re interacting with a database or API, you can call them via a protocol. This lets you use a different implementation of that protocol — that you can control — when running your tests. For example, when calling a third-party API, using a protocol makes it easy to test for different responses and errors.
  2. Changing third-party dependencies is easier. Imagine you’re writing a weather app and are using a library to get the weather details for different locations, rainfall information, wind speed and so on. If the library you’re using stops working, or you don’t want to use it anymore, it can be difficult to change it if the library is deeply coupled throughout your codebase. If all the calls to the library are made via a protocol you wrote, then you can pick a new library, write an implementation for your protocol for that library and use it without having to change any other code.
  3. Splitting up your app is easier. When your app becomes large or complex, you’ll want to break it up into different modules. If you define the interactions with those modules via protocols, you can break the work up into different teams and still know how to use the different modules. You can use simple, hard-coded implementations of the protocol until the real module is ready.

You’ll learn more about POP and how to use it in Lesson 3.

See forum comments
Download course materials from Github
Previous: Demo 1 Next: Conclusion