Using a generic class for multiple types

We can create instances of the Party<AnimalElement> class by replacing the AnimalElement generic type parameter with any type name that conforms to the constraints specified in the declaration of the Party<AnimalElement> class. So far, we have three concrete classes that implement both the AnimalProtocol and Equatable protocols: Dog, Frog, and Lion. Thus, we can use Dog to create an instance of Party<Dog>--that is, a Party instance of Dog objects. The following code shows the lines that create four instances of the Dog class: jake, duke, lady, and dakota. Then, the code creates a Party<Dog> instance named dogsParty and passes jake as the leader argument to the initializer. This way, we will create a party of dogs, and Jake is the party leader. The code file for the sample is included in the swift_3_oop_chapter_06_03 folder:

    var jake = Dog(name: "Jake") 
    var duke = Dog(name: "Duke") 
    var lady = Dog(name: "Lady") 
    var dakota = Dog(name: "Dakota") 
    var dogsParty = Party<Dog>(leader: jake) 

The dogsParty instance will only accept a Dog instance for all the arguments in which the class definition uses the generic type parameter named AnimalElement. The following lines add the previously created three instances of Dog to the dogs' party by calling the add method. The code file for the sample is included in the swift_3_oop_chapter_06_03 folder:

    dogsParty.add(member: duke) 
    dogsParty.add(member: lady) 
    dogsParty.add(member: dakota) 

The following lines call the dance method to make all the dogs dance, remove a member that isn't the party leader, vote a new leader, and finally call the sing method to make all the dogs sing. We will add the try keyword before the calls to remove and voteLeader because these methods can throw exceptions. In this case, we don't check the result returned by remove. The code file for the sample is included in the swift_3_oop_chapter_06_03 folder:

    dogsParty.dance() 
    try dogsParty.remove(member: duke) 
    try dogsParty.voteLeader() 
    dogsParty.sing() 

The following lines create an instance of the Dog class named coby. Then, the code calls the removeMember method and prints a message in case the method returns an instance of Dog. If the optional Dog (Dog?) returned by the method does not contain a value, the code prints a message indicating that the dog isn't removed. Because we haven't added Coby to the dog's party, it won't be removed. Then, we will use similar code to remove lady. In case she was selected as the random leader, the method will throw an exception. In case she wasn't selected, the code will print a message indicating that lady is removed. Remember that the remove method returns AnimalElement?, which in this case is translated into a Dog? return type. The code file for the sample is included in the swift_3_oop_chapter_06_03 folder:

    var coby = Dog(name: "Coby") 
    if let removedMember = try dogsParty.remove(member: coby) { 
      print("(removedMember.name) has been removed") 
    } else { 
      print("(coby.name) hasn't been removed") 
    } 
    if let removedMember = try dogsParty.remove(member: lady) { 
      print("(removedMember.name) has been removed") 
    } else { 
      print("(lady.name) hasn't been removed") 
    } 

The following lines show the output after we run the preceding code snippets in the Playground. However, don't forget that there is a random selection of the new leader, and the results will vary in each execution. In case you run the code in the web-based sandbox or Swift on Linux, you will see a few warnings and a fatal error in case the execution generates that the party leader has to be removed. Remember to run the code many times to see the effects of the different flows:

Jake welcomes Duke: Wooooof
Jake welcomes Lady: Wooooof
Jake welcomes Dakota: Wooooof
Jake dances /- - /-/
Duke dances /- - /-/
Lady dances /- - /-/
Dakota dances /- - /-/
Duke says goodbye to Jake: Woof Wooooof Grr
Jake says: Dakota has been voted as our new party leader.
Dakota dances /- - /-/
Jake sings: Woof Woof Woof . Woof Woof . Woof . 
Lady sings: Woof Woof Woof . Woof Woof . Woof . 
Dakota sings: Woof Woof Woof . Woof Woof . Woof . 
Coby hasn't been removed
Lady says goodbye to Dakota: Woof Wooooof Grr
Lady has been removed

The following screenshot shows the Playground with the execution results:

Using a generic class for multiple types

We can use Frog to create an instance of Party<Frog>. The following code creates four instances of the Frog class: frog1, frog2, frog3, and frog4. Then, the code creates a Party<Frog> instance named frogsParty and passes frog1 as the leader argument. This way, we can create a party of frogs, and Frog #1 is their party leader. The code file for the sample is included in the swift_3_oop_chapter_06_04 folder:

    var frog1 = Frog(name: "Frog #1") 
    var frog2 = Frog(name: "Frog #2") 
    var frog3 = Frog(name: "Frog #3") 
    var frog4 = Frog(name: "Frog #4") 
    var frogsParty = Party<Frog>(leader: frog1) 

The frogsParty instance will only accept a Frog instance for all the arguments in which the class definition uses the generic type parameter named T. The following lines add the previously created three instances of Frog to the frogs' party by calling the add method. The code file for the sample is included in the swift_3_oop_chapter_06_04 folder:

    frogsParty.add(member: frog2) 
    frogsParty.add(member: frog3) 
    frogsParty.add(member: frog4) 

The following lines call the dance method to make all the frogs dance, remove a member that isn't the party leader, vote a new leader, and finally call the sing method to make all the frogs sing. The code file for the sample is included in the swift_3_oop_chapter_06_04 folder:

    frogsParty.dance() 
    try frogsParty.remove(member: frog3) 
    try frogsParty.voteLeader() 
    frogsParty.sing() 

The following lines show the output after we run the preceding code snippets in the Playground. However, don't forget that there is a random selection of the new frog's party leader, and the results will vary in each execution:

Frog #1 welcomes Frog #2: Croak
Frog #1 welcomes Frog #3: Croak
Frog #1 welcomes Frog #4: Croak
Frog #1 dances /| |/ ^ ^ 
Frog #2 dances /| |/ ^ ^ 
Frog #3 dances /| |/ ^ ^ 
Frog #4 dances /| |/ ^ ^ 
Frog #3 says goodbye to Frog #1: Ribbit Croak Croooaaak
Frog #1 says: Frog #2 has been voted as our new party leader.
Frog #2 dances /| |/ ^ ^ 
Frog #1 sings: Ribbit Ribbit Ribbit . Ribbit Ribbit . Ribbit . 
Frog #2 sings: Ribbit Ribbit Ribbit . Ribbit Ribbit . Ribbit . 
Frog #4 sings: Ribbit Ribbit Ribbit . Ribbit Ribbit . Ribbit . 

The following screenshot shows the Playground with the execution results:

Using a generic class for multiple types

We can use Lion to create an instance of Party<Lion>. The following code creates three instances of the Lion class: simba, nala, and mufasa. Then, the code creates a Party<Lion> instance named lionsParty and passes simba as the leader argument. This way, we can create a party of lions, and Simba is the party leader. The code file for the sample is included in the swift_3_oop_chapter_06_05 folder:

    var simba = Lion(name: "Simba") 
    var nala = Lion(name: "Nala") 
    var mufasa = Lion(name: "Mufasa") 
    var lionsParty = Party<Lion>(leader: simba) 

The lionsParty instance will only accept a Lion instance for all the arguments in which the class definition uses the generic type parameter named AnimalElement. The following lines add the previously created two instances of Lion to the lions' party by calling the add method. The code file for the sample is included in the swift_3_oop_chapter_06_05 folder:

    lionsParty.add(member: nala) 
    lionsParty.add(member: mufasa) 

The following lines call the sing method and then the dance method to make all the lions sing and dance. Then, the code calls the voteLeader method to select a new random leader and finally tries to remove nala from the party by calling the remove method. The code file for the sample is included in the swift_3_oop_chapter_06_05 folder:

    lionsParty.sing() 
    lionsParty.dance() 
    try lionsParty.voteLeader() 
    try lionsParty.remove(member: nala) 

The following lines show the output after we run the preceding code snippets in the Playground:

Simba welcomes Nala: Rrroarrr
Simba welcomes Mufasa: Rrroarrr
Simba sings: Roar Roar Roar . Roar Roar . Roar . 
Nala sings: Roar Roar Roar . Roar Roar . Roar . 
Mufasa sings: Roar Roar Roar . Roar Roar . Roar . 
Simba dances *-* ** *|* ** 
Nala dances *-* ** *|* ** 
Mufasa dances *-* ** *|* ** 
Simba says: Mufasa has been voted as our new party leader.
Mufasa dances *-* ** *|* ** 
Nala says goodbye to Mufasa: Roar Rrroarrr Rrrrrrroarrrrrr

The following screenshot shows the Playground with the execution results:

Using a generic class for multiple types

If we try to call the add method with the wrong type in the member argument for an instance of Party<Lion>, the code won't compile. For example, if we pass a Dog instance in the member argument, Swift cannot convert an instance of Dog to the required argument type (Lion). Thus, the following line won't be executed in the Playground because lady is an instance of Dog. The code file for the sample is included in the swift_3_oop_chapter_06_06 folder:

    lionsParty.add(member: lady) 

The following lines show the error message indicating to us that Swift cannot convert Dog to Lion:

error: cannot convert value of type 'Dog' to expected argument type 'Lion'
lionsParty.add(member: lady)
                       ^~~~
..................Content has been hidden....................

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