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:
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.
3.137.161.251