Study Notes for version 2 of Swift2 Development Guide (Day48) -- type check and conversion 
 
 Inheritance occurs between the Child class and the parent class. It is an inheritance relationship of a series of classes. 
 
 For example, Person is the root class in the class hierarchy, Student is the direct subclass of Person, and Worker is the direct subclass of Person. 
 
 The specific implementation code of this inherited link class is as follows: 
 
   
 
class Person {
     var name: String
     var age: Int
    
     func description ()-> String {
         return "\ (name) age is: \ (age)"
     }
     convenience init () {
         self.init (name: "Tony")
         self.age = 18
     }
     convenience init (name: String) {
         self.init (name: name, age: 18)
     }
     init (name: String, age: Int) {
         self.name = name
         self.age = age
     }
}
 
class Student: Person {
     var school: String
     init (name: String, age: Int, school: String) {
         self.school = school
         super.init (name: name, age: age)
     }
}
 
class Worker: Person {
     var factory: String
     init (name: String, age: Int, factory: String) {
         self.factory = factory
         super.init (name: name, age: age)
     }
}
 
 
   
 
   
 
 The following describes the type check and conversion of Swift classes, including the is Operator and as operator. 
 
   
 
 Use the is Operator 
 
 The is operator can determine whether an instance is of a class type. If the instance is of the target type, true is returned; otherwise, false is returned. 
 
 The following is an example: 
 
 Let student1 = Student (name: "Tom", age: 18, school: "Tsinghua University") // create a Student instance 
 
 Let student2 = Student (name: "Ben", age: 28, school: "Peking University") // create a Student instance 
 
 Let student3 = Student (name: "Tony", age: 38, school: "") // create a Student instance 
 
   
 
 Let worker1 = Worker (name: "Tom", age: 18, factory: "steel mill") // create a Worker instance 
 
 Let worker2 = Worker (name: "Ben", age: 20, factory: "Power Plant") // create a Worker instance 
 
   
 
 Let people = [student1, student2, student3, worker1, worker2] // Add the instance to the people array set 
 
   
 
 Var studentCount = 0 
 
 Var workerCount = 0 
 
   
 
 For item in people {// use for in to traverse the people array set 
 
 If item is Worker { 
 
 ++ WorkerCount 
 
 } Else if item is Student { 
 
 ++ StudentCount 
 
 } 
 
 } 
 
   
 
 Print ("worker count: \ (workerCount), student count: \ (studentCount ). ") 
 
 We can judge in the loop body that the item is Worker expression is used to determine whether the elements in the set are instances of the Worker class. 
 
 Similarly, the item is Student expression is used to determine whether the element in the set is an instance of the Student class. 
 
 The output result is as follows: 
 
 Number of workers: 2; Number of students: 3. 
 
   
 
 Use the as operator 
 
 Before introducing the as operator, let's take a look at object type conversion. Not all types can be converted to each other. See the following statement first: 
 
 Let p1: Person = Student (name: "Tom", age: 20, school: "Tsinghua University ") 
 
 Let p2: Person = Worker (name: "Tom", age: 18, factory: "steel mill ") 
 
 Let p3: Person = Person (name: "Tom", age: 28) 
 
 Here, three instances p1, p2, and p3 are created, all of which belong to the Person type. P1 is a Student instance, p2 is a Worker instance, and p3 is a Person instance. First, object type conversion must take place under the premise of inheritance, p1 and p2 are declared as the Person type, and the instance is instantiated by the Person subtype. 
 
 As the creator of this program, we know that p1 is essentially a Student instance, but on the surface it is a Person type, and the compiler cannot infer whether the p1 instance is Person, Student, or Worker. We can use the is operator to determine which type of instances it is. Then, you can use the as operator to convert the type of Person to the subclass type, that is, to convert the p1 type of Person to the Student subclass type. This type of conversion is called downward transformation. This conversion is risky. If p1 is not the target type, the conversion will fail. To avoid exceptions, we can use? Convert it to an optional type of the target type. If it succeeds, it is converted. If it fails, nil is returned. 
 
   
 
 P3 differs greatly from p1 and p2 because p3 is essentially a Person instance and cannot be transformed downward. 
 
 The following is an example: 
 
   
 
let student1 = Student (name: "Tom", age: 18, school: "Tsinghua University")
let student2 = Student (name: "Ben", age: 28, school: "Peking University")
let student3 = Student (name: "Tony", age: 38, school: "The University of Hong Kong")
 
let worker1 = Worker (name: "Tom", age: 18, factory: "steel factory")
let worker2 = Worker (name: "Ben", age: 20, factory: "power plant")
 
let people = [student1, student2, student3, worker1, worker2]
 
for item in people {
    
     if let student = item as? Student {
         print ("Student school: \ (Student.school)")
     } else if let worker = item as? Worker {
         print ("Worker factory: \ (Worker.factory)")
     }
}
 
 
   
 
 Use for in to traverse the people array set. In the loop body, letstudent = item? Student statement using? The operator converts an element to the Student type. If the conversion is successful, assign the element to the Student variable. Otherwise, assign the nil value to the Student variable and execute the code successfully. 
 
 The output result is as follows: 
 
 Student school: Tsinghua University 
 
 Student school: Peking University 
 
 Student school: Hong Kong University 
 
 Worker factory: steel mills 
 
 Worker factory: Power Plant 
 
   
 
 As? The operator is used when you are not sure whether the type conversion is successful. If the conversion result is successful, the type is optional. If we can ensure the conversion is successful, we can use! The operator is implicitly split during conversion. 
 
 The sample code is as follows: 
 
...
let people = [student1, student2, student3, worker1, worker2]
...
let stud1 = people [0] as? Student // The first element of the people array
print (stud1)
print (stud1! .name)
 
let stud2 = people [1] as! Student // The second element of the people array
print (stud2)
print (stud2.name) 
 
   
 
   
 
   
 
 Output result: 
 
 Optional (Student) 
 
 Student 
 
 The first element of the people array in the code, using? The operator is converted to the Student type, and the conversion is successful to Optional (Student), that is, the Student type is Optional. 
 
 The second element of the people array in the code, using! The operator is converted to the Student type. The conversion is successful to the Student type instance instead of the Student type.