Default implementations
It is possible to provide default implementations for protocols through extensions. Previously, we provided a partial default implementation for the Toggling protocol on a well-known type. But any other type, that would conform to Toggling needs to provide an implementation on isActive. Using another example, let's look at how we can leverage default implementations in protocol extensions without requiring additional conformance work.
Let's work with a simple protocol, Adder, for the sake of the example:
protocol Adder {
func add(value: Int) -> Int
func remove(value: Int) -> Int
}
The Adder protocol declares two methods: add and remove. And, if we remember our math classes well, we can very well declare remove as a function of add. Removing is just adding a negative value. Protocol extension allows us to do just that:
extension Adder {
func remove(value: Int) -> Int {
return add(value: -value)
}
}
This may look a bit silly, but in reality, this pattern is really powerful. Remember, we were able to implement remove because we were able to express it as a function of another provided method. Often, in our code, we can implement a method as a function of another. Protocols give us a contract that is fulfilled by either the concrete type or the extension, and we can effectively and expressively compose our programs around those capabilities.