Declaring a class that conforms to multiple protocols

Now, we will declare a class named Animal that conforms to both the previously defined AnimalProtocol and Equatable protocols. The latter is a fundamental type in Swift. In order to conform to the Equatable protocol, we must implement the == operator function for the Animal class to determine the equality of the instances after we declare the class. This way, we will be able to determine the equality of the instances of classes that implement the AnimalProtocol protocol. We can read the class declaration as "the Animal class implements both the AnimalProtocol and Equatable protocols." Take a look at the following code. The code file for the sample is included in the swift_3_oop_chapter_06_01 folder:

    open class Animal: AnimalProtocol, Equatable {
      open let name: String
  
      open var danceCharacters: String {
        get {
          return String()
        }
      }
 
      open var spelledSound1: String {
        get {
          return String()
        } 
      }
   
      open var spelledSound2: String {
        get {
          return String()
        }
      }
   
      open var spelledSound3: String {
        get {
          return String()
        }
      }
   
      public required init(name: String) {
        self.name = name
      }
   
      open func dance() {
        print("(name) dances (danceCharacters)")
      }
   
      open func say(message: String) {
        print("(name) says: (message)")
      }
  
      open func sayGoodbyeTo(destination: AnimalProtocol) {

        print("(name) says goodbye to (destination.name): 
        (spelledSound1) (spelledSound2) (spelledSound3)")
      }
   
      open func sayWelcomeTo(destination: AnimalProtocol) {
        print("(name) welcomes (destination.name): (spelledSound2)")
      }
 
      open func sing() {
        let spelledSingSound = spelledSound1 + " ";
        let separator = ". "
        var song = "(name) sings: "
  
        for _ in 1...3 {
          song += spelledSingSound
        }
        song += separator
        for _ in 1...2 {
          song += spelledSingSound
        }  
        song += separator  
        song += spelledSingSound
        song += separator
   
        print(song)
      }
    }
  
    public func ==(left: Animal, right: Animal) -> Bool {
      return ((type(of: left) == type(of: left)) && (left.name == 
      right.name))
    }

The Animal class declares an initializer that assigns the value of the required name argument to the read-only name stored property. Note that the initializer declaration uses the required keyword because it implements the initializer requirement specified in the AnimalProtocol protocol. A required initializer must be as accessible as its enclosing type. In this case, the enclosing type is the Animal class, declared with the open access modifier. We must use public to declare the required initializer because open cannot be used with initializers:

    public required init(name: String) { 

The class declared the following four String computed read-only properties. All of them define a getter method that returns an empty string and that the subclasses will override, with appropriate strings according to the animal:

  • danceCharacters
  • spelledSound1
  • spelledSound2
  • spelledSound3

The dance method uses the value retrieved from the danceCharacters property to print a message indicating that the animal is dancing. The say method prints the message received as an argument. Both the sayWelcomeTo and sayGoodbyeTo methods receive AnimalProtocol as an argument, which they use to print the name of the destination of the message. The sayWelcomeTo method uses a combination of the strings retrieved from spelledSound1 and spelledSound3 to say welcome to another animal. The sayGoodbyeTo method uses the string retrieved from spelledSound2 to say goodbye to another animal.

The == operator function receives two Animal instances as arguments and checks whether the value of the name property and type for both the instances are the same. In a more complex scenario, we might want to code this method to compare the values of more properties to determine the equality. In our case, we will assume that the same animal with the same name is exactly the same animal. For example, two frogs named Kermit are considered to be one frog. Remember that we need to write the == operator function to make the Animal class conform to the Equatable protocol. If we comment out the lines that declare the == operator function, the Animal class won't conform to the Equatable protocol anymore. The code file for the sample is included in the swift_3_oop_chapter_06_02 folder:

    /* public func ==(left: Animal, right: Animal) -> Bool { 
      return ((left.dynamicType == right.dynamicType) && (left.name == 
      right.name)) 
    } */ 

After we comment out the previous lines, the execution in the Playground will fail, and we will see the following error:

    error: type 'Animal' does not conform to protocol 'Equatable' 
    open class Animal: AnimalProtocol, Equatable { 
               ^ 

Swift indicates to us that the class doesn't conform to the Equatable protocol. The following screenshot shows the Playground with the generated error after we comment out the previous lines that declared the == operator function:

Declaring a class that conforms to multiple protocols

Now that we have checked the results of removing the lines that declared the == operator function, we can uncomment it, and the Animal class will conform to the Equatable protocol again. The code file for the sample is included in the swift_3_oop_chapter_06_03 folder.

..................Content has been hidden....................

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