When defining a protocol, we might want to provide a default implementation of its properties and functions. This is useful in cases where the implementation of the functions and properties remain the same across the classes, structs, and enums that conform to this protocol.
Take protocol PenSelling
defined below:
protocol PenSelling { var penPrice: Int { get } func price(withPenCount count: Int) -> Int }
Any store that sells pens needs to have a price for each pen and a method to calculate the total price for count
pens.
We can use a protocol extension to provide default implementations for both:
extension PenSelling { var penPrice: Int { return 2 } func price(withPenCount count: Int) -> Int { return penPrice * count } }
In an extension for a protocol, you can provide default implementations of its requirements.
Any stores that conform to this protocol will automatically have a penPrice
of 2 and the above implementation of price(withPenCount:)
without writing any code!
struct Bookstore: PenSelling { let name: String } let miasStore = Bookstore(name: "Mia's Books") print(miasStore.price(withPenCount: 10)) // prints 20
Conforming types can also choose to provide their own implementations for any or all of the properties and methods.
struct ArtStore: PenSelling { let name: String var penPrice: Int = 5 } let noahsStore = ArtStore(name: "Noah's Art Supplies") print(noahsStore.price(withPenCount: 10)) // prints 50
Instructions
Add a protocol extension to IceCreamSelling that provides a default implementation for flavors
. It should return ["Vanilla", "Chocolate"]
.
Make IceCreamTruck
and IceCreamParlor
both conform to IceCreamSelling
. IceCreamTruck
should use the default implementation and IceCreamParlor
should return a flavors
array of ["Mint Chip", "Strawberry", "Cookie Dough"]
.
Print out the flavors
for misterSoftee
and popTates
.