Adopting and Conforming a Class, Structure, or Enumeration to a Swift Protocol

By Jesse Feiler

Any of the major types (classes, structures, and enumerations) can adopt protocols. You can create a protocol that is adopted by any of them, or you can specify that it is adoptable only by a class. Here are examples of conforming to the basic protocol (MyProtocol).

Conforming a class to a protocol

Many of the protocols used in the Cocoa and Cocoa Touch frameworks are adopted by classes in the frameworks in part because in Objective‐C, protocols are typically used only with classes. You’ll be able to move beyond classes, but, when you’re writing code that uses the frameworks, you’ll frequently have to write code that conforms to protocols for classes.

Here are a few guidelines to conforming classes to protocols:

  • You specify that a class adopts a protocol in its declaration, as in the following:

    class MyClass: MyProtocol {
  • If you adopt more than one protocol, separate them with commas, as in the following:

    class MyClass: MyProtocol, MyProtocol2 {
  • If your class is a subclass of another class, its superclass appears first in the list, as in the following:

    class MyClass: MySuperclass, MyProtocol2

    Remember that Swift does not support multiple inheritance, so there can only be one superclass (or none). You can add protocols to the list if necessary.

If your class is a subclass of a class that adopts a protocol, you must conform to that protocol in your own class unless the superclass already conforms to it. You don’t specify this inherited adopted protocol in your own declaration.

Having indicated that your class adopts a protocol, you must now implement all of the required properties and methods. (It’s possible to signify that some methods and properties are optional, but the default setting is that they are all required.)

Here is an example of a class that conforms to a protocol. Note that myFunc is required by the protocol, whereas intVal is a class property that has nothing to do with the protocol:

class MyClass: MyProtocol {
  func myFunc () -> String {
    return "Protocol 1"
  }
  var intVal: Int = 0
}

You can create a variable (with var) or constant (with let) that contains an instance of the class with this code:

var myClass: MyClass = MyClass()

You can then access the class’s intVal instance property as well as the protocol’s required method myFunc:

myClass.intVal = 25
myClass.myFunc()

At this point, you make no distinction between the methods and properties required by the protocol and those that are simply part of the class.

Conforming a structure to a protocol

A structure (struct) adopts a protocol in the same way as a class does — with code like this:

struct MyStruct: MyProtocol {
  func myFunc () -> String {
    return "Protocol 2"
  }
  var intVal: Int = 0
  var One = 1
  var Two = 2
}

You can declare a variable that uses the structure. You can then access the members of the structure as well as the function that’s required by the protocol:

var myStruct: MyStruct = MyStruct()
myStruct.intVal = 15
myStruct.myFunc()

Conforming an enumeration to a protocol

Enumerations follow the same basic design. You can declare an enumeration that adopts a protocol alongside its own data, as in the following code:

enum MyEnum: MyProtocol {
  func myFunc () -> String {
    return "Protocol 3"
  }
  case One
  case Two
  case Three
  case Four
}

Then, use the enumeration with a variable in your code:

var myEnum: MyEnum = MyEnum.Two
myEnum.myFunc ()

Putting it all together

The following listing shows these samples put together.

// Playground - noun: a place where people can play
protocol MyProtocol {
  func myFunc () -> String
}
class MyClass: MyProtocol {
  func myFunc () -> String {
    return "Protocol 1"
  }
  var intVal: Int = 0
}
var myClass: MyClass = MyClass()
myClass.intVal = 25
myClass.myFunc()
struct MyStruct: MyProtocol {
  func myFunc () -> String {
    return "Protocol 2"
  }
  var intVal: Int = 0
  var One = 1
  var Two = 2
}
enum MyEnum: MyProtocol {
  func myFunc () -> String {
    return "Protocol 3"
  }
  case One
  case Two
  case Three
  case Four
}
var myStruct: MyStruct = MyStruct()
myStruct.intVal = 15
myStruct.myFunc()
var myEnum: MyEnum = MyEnum.Two
myEnum.myFunc ()