Learn

A protocol defines a blueprint or a set of requirements that are needed to accomplish a particular task. Classes, structs, and enums can conform to protocols by providing an implementation of the protocol’s functions and properties.

The definitions of protocols are very similar to classes and structs. However, in the case of protocols, the definition does not implement the properties and functions. Instead, the class or struct that adopts the protocol handles the implementation of the properties and methods. Any type that satisfies the requirements of the protocol as described above is said to conform to the protocol.

protocol WelcomeMessagePrinting { func printHello(message: String) }

In the example above, we have a protocol named PrintMessage. Inside the protocol, there is a function called printHello(). This function would be implemented by the class or struct that adopts PrintMessage.

struct MyStruct: WelcomeMessagePrinting { func printHello(message: String) { print(message) } }

As mentioned earlier, properties can also be a part of protocols.

protocol WelcomeMessagePrinting { var helloMessage: String { get } func printHello() }

Notice that in the above example we have introduced a String type property named helloMessage. There are a couple of things to know here:

  • The protocol definition must specify if the conforming class/struct/enum needs to implement just the getter for the property or both the getter and setter methods.
  • If the property is defined as get, then the conforming type can choose to either provide the getter method, which is the minimum requirement or provide both the getter and setter methods.

Let’s now create a struct that conforms to WelcomeMessagePrinting:

struct Hello: WelcomeMessagePrinting { var helloMessage: String { return "Welcome" } func printHello() { print(helloMessage) } }

Note that to add protocol conformance, the struct Hello needs to be followed by a : and the protocol name.

Sometimes protocols have multiple functions and the implementation can be long, so it is common to move the protocol implementation to a separate extension as follows:

extension Hello: HelloPrinting { var helloMessage: String { return "Welcome" } func printHello() { print(helloMessage) } }

The printHello() function can then be called as follows:

let hello = Hello() hello.printHello() // Prints: Welcome

Multiple types can conform to the same protocol. For instance, in the following example we have NewUserWelcomeView struct conforming to WelcomeMessagePrinting:

struct NewUserWelcomeView: WelcomeMessagePrinting { var welcomeMessage: String = "Thanks for signing up!" func printWelcome() { print(welcomeMessage) } }

And then the ReturningUserWelcomeView also conforms to WelcomeMessagePrinting:

struct ReturningUserWelcomeView: WelcomeMessagePrinting { var welcomeMessage: String = "Welcome back!" func printWelcome() { print(welcomeMessage) } }

Note that the welcomeMessage for the structs above are different - that’s the flexibility that protocols allow us.

We can invoke the printWelcome function on instances of the structs as given below:

var view: WelcomeMessagePrinting view = NewUserWelcomeView() view.printWelcome() view = ReturningUserWelcomeView() view.printWelcome()

Note that view is declared as WelcomeMessagePrinting type, which means that it can be of any type that conforms to the WelcomeMessagePrinting protocol.

Instructions

1.

Create a protocol named Incrementable that has a property called currentValue of type Double and a get method. It should also have a mutating function called increment() that takes no arguments and does not return anything.

2.

Create a struct named VisitorCounter that conforms to Incrementable. Add a currentValue property and assign it 0.0. Add an increment() method that increases the value of currentValue by 1.

3.

Create another struct named Wage that conforms to Incrementable. Set currentValue to 15.0 in this case. In the implementation of increment(), increase the value of currentValue by 10%.

4.

Create a variable called parkGuests of type VisitorCounter. Call increment on parkGuests and print the currentValue of parkGuests.

5.

Create a variable called salary of type Wage. Call increment() on salary. Then print the currentValue of salary.

Take this course for free

By signing up for Codecademy, you agree to Codecademy's Terms of Service & Privacy Policy.
Already have an account?