Chapter 5. Contract Programming with Protocols

In this chapter, we will work with more complex scenarios in which we will have to use instances that belong to more than one blueprint. We will use contract programming by taking advantage of protocols.

We will work with examples on how to define protocols and their different kinds of requirements, and then on how to declare classes that adopt the protocols. We will use multiple inheritance of protocols and many useful ways of taking advantage of this object-oriented concept, also known as interfaces in other programming languages such as Java and C#.

Understanding how protocols work in combination with classes

We have to work with two different types of characters: comic and game characters. A comic character has a nickname and must be able to draw speech balloons and thought balloons. The speech balloon might have another comic character as a destination.

A game character has a full name and must be able to perform the following tasks:

  • Draw itself at a specific 2D position indicated by the x and y coordinates
  • Move itself to a specific 2D position indicated by the x and y coordinates
  • Check whether it intersects with another game character

We will work with objects that can be both a comic character and a game character. However, we will also work with objects that will just be either a comic or game character. Neither the game character nor the comic character has a generic way of performing the previously described tasks. Thus, each object that declares itself as a comic character must define the tasks related to speech and thought balloons. Each object that declares itself as a game character must define how to draw itself, move, and check whether it intersects with another game character.

An angry dog, also known as grumpy dog, is a comic character that has a specific way of drawing speech and thought balloons. An angry cat is both a comic and game character, so it defines all the tasks required by both character types.

The angry cat, also known as grumpy cat, is a very versatile character, and it can use different costumes to participate in either games or comics with different names. An angry cat can also be an alien, a wizard, or a knight:

  • An alien has a specific number of eyes and must be able to appear and disappear.
  • A wizard has a spell power score and can make an alien disappear.
  • A knight has sword power and weight values, and can unsheathe his sword. A common task for the knight is to unsheathe his sword and point it at an alien as a target.

We need base blueprints to represent a comic character and a game character. Then, each class that represents any of these types of characters can provide its implementation of the methods. In this case, comic and game characters are very different, and they don't perform similar tasks that might lead to confusion and problems for multiple inheritance. Thus, we can use multiple inheritance to create an angry cat class that implements both comic and game character blueprints. In some cases, multiple inheritance is not convenient because similar blueprints might have methods with the same names, and it can therefore be extremely confusing to use multiple inheritance.

In addition, we can use multiple inheritance to combine the angry cat class with alien, wizard, and knight. This way, we will have an angry cat alien, an angry cat wizard, and an angry cat knight. We will be able to use any of them, the angry cat alien, angry cat wizard, or angry cat knight, as either a comic or game character.

Our goals are simple, but we face a little problem: Swift doesn't support the multiple inheritance of classes. Instead, we can use multiple inheritance with protocols or combine protocols with classes. So, we will use protocols and classes to fulfill our previous requirements.

You can think of a protocol as a special case of an abstract class that defines the initializers, properties, and methods that a class must implement to be considered a member of the group identified with the protocol name.

Tip

If you have worked with other programming languages, such as Java and C#, you can think of protocols as the Swift version of interfaces.

For example, we can create an Alien protocol that specifies the following elements:

  • A numberOfEyes property
  • A parameterless method named appear
  • A parameterless method named disappear

Once we define a protocol, we create a new type; therefore, we can use it to specify the required type for an argument. This way, instead of using classes as types, we will use protocols as types, and we can use an instance of any class that conforms to the specific protocol as an argument. For example, if we use Alien as the required type for an argument, we can pass an instance of any class that conforms to the Alien protocol as an argument.

However, you must take into account some limitations of protocols when compared with classes. Protocols cannot specify accessibility modifiers to any member. Protocols can declare requirements for the following members:

  • Properties
  • Methods
  • Mutating methods
  • Initializers
  • Failable initializers
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.189.211