Learn how protocol inheritance is a powerful feature that lets us create more granular designs.
- [Instructor] A protocol can inherit from one or more protocols and add new requirements on top of the inherited ones. A protocol inheritance is a powerful feature which lets create more granular designs. Let's open the project by going through the desktop. Exercise files, chapter two 0 two 0 five start and opening the protocol inheritance playground. So, here is the binary representable protocol.
Now, lets assume that we want to add new requirements. Say, we need the ability to save instances to the local storage and restore them later on. Also, we need support for Base64 encoding. We could squeeze in all the functionality in this protocol. Yet, this means that we assign unrelated responsibilities like persistence and Base64 encoding to this protocol. This is a bad sign and it leads to the same issue we had with monolithics superclasses.
Instead, we create dedicated protocols for each requirement set. First, we create the protocol that defines the persistence related requirements. I'm going to call it, Binary Persistable. The binary persistable protocol inherits from binary representable. That means that conforming types must implement the property and math requirements from both protocols. Binary persistable adds an initializer and a method requirement.
Let's start with the initializer. The initializer takes a tag argument of type, String. This argument, identifies the instance to be restored. The contents of parameter is the URL to read from and I mark the initializer as, "throwable" using the throws keyword. This makes sense since there may be different problems when dealing with persistence. Think of issues like missing files lack of permissions and so on.
Next, I declare the persist method. It takes the URL argument which represents the storage location. This method is also throwable, so we mark it as such. Protocol inheritance is similar to class inheritance. The big difference is that protocols can inherit from multiple protocols. For example, we could add further requirements to adopters of binary persistable. Let's add "Custom String Convertible".
This protocol allows us to provide custom descriptions for our types. Also, we could add the equatable protocol to the inheritance list which means that our types must provide the equitity operator. So, if we implement the type which conforms to the binary persistable protocol we'd have to implement the requirements for binary representable binary persistable, custom string convertible and equatable.
Similarly, we create a protocol for the Base64 encoding. I'm going to call it, Base64 Encodable. The Base64 encodable defines the Base64 property requirement which returns the instance Base64 encoded string representation. It is going to be a string and let's make it read-only by making it a gettable property.
Like binary persistable, the Base64 encodable protocol also inherits from binary representable. Now, any new type can decide which requirements to implement. Binary representable if they only need a type holding data that can be tagged. Binary persistable if persistence is also needed or Base64 encodable if Base64 string representation is what we want for that type.
Or, it can implement all of these protocols. Since the type can adapt multiple protocols we can also create types which implement the requirements defined in all three protocols. Protocol inheritance is a useful feature which lets us create better granular designs.
- Comparing object-oriented programming with protocol-oriented programming
- Methods and class-bound protocols
- Adopting a protocol
- Declaring asynchronous behavior
- Preparing and implementing fallback logic
- Implementing an app using protocol-oriented programming