继承会发生在子类和父类之间,是一系列类的继承关系。@H_502_1@@H_502_1@
@H_502_1@例如:@H_502_1@@H_502_1@Person@H_502_1@@H_502_1@是类层次结构中的根类,@H_502_1@@H_502_1@Student@H_502_1@@H_502_1@是@H_502_1@@H_502_1@Person@H_502_1@@H_502_1@的直接子类,@H_502_1@@H_502_1@Worker@H_502_1@@H_502_1@是@H_502_1@@H_502_1@Person@H_502_1@@H_502_1@的直接子类。@H_502_1@@H_502_1@
@H_502_1@这个继承关系类的具体实现代码如下:@H_502_1@@H_502_1@
@H_502_1@@H_502_1@
class Person { var name: String var age: Int func description() -> String { return "\(name) 年龄是: \(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,factory: String) { self.factory = factory super.init(name: name,age: age) } }
@H_502_1@
下面将以此为例,介绍@H_502_1@Swift@H_502_1@@H_502_1@类的类型检查与转换,包括@H_502_1@@H_502_1@is@H_502_1@@H_502_1@操作符、@H_502_1@@H_502_1@as@H_502_1@@H_502_1@操作符。@H_502_1@@H_502_1@
@H_502_1@ @H_502_1@使用@H_502_1@is@H_502_1@@H_502_1@操作符@H_502_1@@H_502_1@
@H_502_1@is@H_502_1@@H_502_1@操作符可以判断一个实例是否是某个类的类型。如果实例是目标类型,结果返回@H_502_1@@H_502_1@true@H_502_1@@H_502_1@,否则为@H_502_1@@H_502_1@false@H_502_1@@H_502_1@。@H_502_1@@H_502_1@
@H_502_1@ @H_502_1@let @H_502_1@s@H_502_1@tudent1 = Student(name@H_502_1@: @H_502_1@"Tom",age@H_502_1@: @H_502_1@18,school@H_502_1@: @H_502_1@"@H_502_1@清华大学@H_502_1@@H_502_1@")@H_502_1@//@H_502_1@创建@H_502_1@@H_502_1@Student@H_502_1@实例@H_502_1@@H_502_1@
@H_502_1@let @H_502_1@s@H_502_1@tudent2 = Student(name@H_502_1@: @H_502_1@"Ben",age@H_502_1@: @H_502_1@28,school@H_502_1@: @H_502_1@"@H_502_1@北京大学@H_502_1@@H_502_1@")@H_502_1@//@H_502_1@创建@H_502_1@@H_502_1@Student@H_502_1@实例@H_502_1@@H_502_1@
@H_502_1@let @H_502_1@s@H_502_1@tudent3 = Student(name@H_502_1@: @H_502_1@"Tony",age@H_502_1@: @H_502_1@38,school@H_502_1@: @H_502_1@"@H_502_1@香港大学@H_502_1@@H_502_1@")@H_502_1@//@H_502_1@创建@H_502_1@@H_502_1@Student@H_502_1@实例@H_502_1@@H_502_1@
@H_502_1@@H_502_1@
@H_502_1@let @H_502_1@w@H_502_1@orker1 = Worker(name@H_502_1@: @H_502_1@"Tom",factory@H_502_1@: @H_502_1@"@H_502_1@钢厂@H_502_1@@H_502_1@")@H_502_1@//@H_502_1@创建@H_502_1@@H_502_1@Worker@H_502_1@@H_502_1@实例@H_502_1@@H_502_1@
@H_502_1@let @H_502_1@w@H_502_1@orker2 = Worker(name@H_502_1@: @H_502_1@"Ben",age@H_502_1@: @H_502_1@20,factory@H_502_1@: @H_502_1@"@H_502_1@电厂@H_502_1@@H_502_1@")@H_502_1@//@H_502_1@创建@H_502_1@@H_502_1@Worker@H_502_1@@H_502_1@实例@H_502_1@@H_502_1@
@H_502_1@@H_502_1@
@H_502_1@let people = [@H_502_1@s@H_502_1@tudent1,@H_502_1@s@H_502_1@tudent2,@H_502_1@s@H_502_1@tudent3,@H_502_1@w@H_502_1@orker1,@H_502_1@w@H_502_1@orker2] @H_502_1@@H_502_1@//@H_502_1@实例放入@H_502_1@@H_502_1@people@H_502_1@@H_502_1@数组集合中@H_502_1@@H_502_1@
@H_502_1@@H_502_1@
@H_502_1@var @H_502_1@s@H_502_1@tudentCount = 0@H_502_1@
@H_502_1@var @H_502_1@w@H_502_1@orkerCount = 0@H_502_1@
@H_502_1@@H_502_1@
@H_502_1@for item in people { @H_502_1@@H_502_1@//@H_502_1@使用@H_502_1@@H_502_1@for in@H_502_1@@H_502_1@遍历@H_502_1@people@H_502_1@@H_502_1@数组集合@H_502_1@@H_502_1@
@H_502_1@@H_502_1@if item is Worker { @H_502_1@@H_502_1@
@H_502_1@@H_502_1@++@H_502_1@w@H_502_1@orkerCount@H_502_1@
@H_502_1@@H_502_1@} else if item is Student { @H_502_1@@H_502_1@
@H_502_1@@H_502_1@++@H_502_1@s@H_502_1@tudentCount@H_502_1@
@H_502_1@ @H_502_1@}@H_502_1@
@H_502_1@@H_502_1@
@H_502_1@print("@H_502_1@工人人数:@H_502_1@@H_502_1@\(@H_502_1@w@H_502_1@orkerCount) @H_502_1@,学生人数:@H_502_1@@H_502_1@\(@H_502_1@s@H_502_1@tudentCount) @H_502_1@。@H_502_1@@H_502_1@")@H_502_1@
@H_502_1@我们可以在循环体中进行判断,@H_502_1@@H_502_1@ item is@H_502_1@@H_502_1@ @H_502_1@@H_502_1@Worker@H_502_1@@H_502_1@表达式是判断集合中的元素是否是@H_502_1@@H_502_1@Worker@H_502_1@@H_502_1@类的实例。@H_502_1@@H_502_1@
@H_502_1@类似地,@H_502_1@@H_502_1@ item is@H_502_1@@H_502_1@ @H_502_1@@H_502_1@Student@H_502_1@@H_502_1@表达式是判断集合中的元素是否是@H_502_1@@H_502_1@Student@H_502_1@@H_502_1@类的实例。@H_502_1@@H_502_1@
@H_502_1@ @H_502_1@工人人数:@H_502_1@@H_502_1@2@H_502_1@,学生人数:@H_502_1@@H_502_1@3@H_502_1@。@H_502_1@@H_502_1@
@H_502_1@ @H_502_1@使用@H_502_1@as@H_502_1@@H_502_1@操作符@H_502_1@@H_502_1@
@H_502_1@在介绍@H_502_1@as@H_502_1@@H_502_1@操作符之前,先了解一下对象的类型转换,并不是所有的类型都能互相转换。下面先看如下语句:@H_502_1@@H_502_1@
@H_502_1@let p1@H_502_1@: @H_502_1@Person = Student(name@H_502_1@: @H_502_1@"Tom",school@H_502_1@: @H_502_1@"@H_502_1@清华大学@H_502_1@@H_502_1@")@H_502_1@
@H_502_1@let p2@H_502_1@: @H_502_1@Person = Worker(name@H_502_1@: @H_502_1@"Tom",factory@H_502_1@: @H_502_1@"@H_502_1@钢厂@H_502_1@@H_502_1@")@H_502_1@
@H_502_1@let p3@H_502_1@: @H_502_1@Person = Person(name@H_502_1@: @H_502_1@"Tom",age@H_502_1@: @H_502_1@28)@H_502_1@
@H_502_1@这里创建了@H_502_1@3@H_502_1@@H_502_1@个实例@H_502_1@p1@H_502_1@@H_502_1@、@H_502_1@p2@H_502_1@@H_502_1@、@H_502_1@p3@H_502_1@@H_502_1@,类型都是@H_502_1@Person@H_502_1@@H_502_1@。@H_502_1@p1@H_502_1@@H_502_1@是@H_502_1@Student@H_502_1@@H_502_1@实例,@H_502_1@p2@H_502_1@@H_502_1@是@H_502_1@Worker@H_502_1@@H_502_1@实例,@H_502_1@p3@H_502_1@@H_502_1@是@H_502_1@Person@H_502_1@@H_502_1@实例。首先,对象类型转换一定发生在继承的前提下,@H_502_1@p1@H_502_1@@H_502_1@和@H_502_1@p2@H_502_1@@H_502_1@都声明为@H_502_1@Person@H_502_1@@H_502_1@类型,而实例是由@H_502_1@Person@H_502_1@@H_502_1@子类型实例化的。@H_502_1@@H_502_1@
@H_502_1@作为这段程序的编写者,我们知道@H_502_1@p1@H_502_1@@H_502_1@本质上是@H_502_1@Student@H_502_1@@H_502_1@实例,但是表面上看是@H_502_1@Person@H_502_1@@H_502_1@类型,编译器也无法推断@H_502_1@p1@H_502_1@@H_502_1@的实例是@H_502_1@Person@H_502_1@@H_502_1@、@H_502_1@Student@H_502_1@@H_502_1@还是@H_502_1@Worker@H_502_1@@H_502_1@。我们可以使用@H_502_1@is@H_502_1@@H_502_1@操作符来判断它是哪一类的实例。然后在转换时可以使用@H_502_1@as@H_502_1@@H_502_1@操作符将其转换为子类类型,即把@H_502_1@Person@H_502_1@@H_502_1@类型的@H_502_1@p1@H_502_1@@H_502_1@转为@H_502_1@Student@H_502_1@@H_502_1@子类类型,这种转换被称为@H_502_1@向下转型@H_502_1@。这种转换是有风险的,如果@H_502_1@p1@H_502_1@@H_502_1@不是目标类型,转换就会失败。为了不发生异常,我们可以使用@H_502_1@as?@H_502_1@@H_502_1@将其转换为目标类型的可选类型,能够成功则转换,不成功则返回@H_502_1@nil@H_502_1@@H_502_1@。@H_502_1@@H_502_1@
@H_502_1@ @H_502_1@p3@H_502_1@@H_502_1@与@H_502_1@p1@H_502_1@@H_502_1@和@H_502_1@p2@H_502_1@@H_502_1@有很大的不同,因为@H_502_1@p3@H_502_1@@H_502_1@本质上是@H_502_1@Person@H_502_1@@H_502_1@实例,不能向下转型。@H_502_1@@H_502_1@
@H_502_1@ @H_502_1@@H_502_1@
let student1 = Student(name: "Tom",age: 18,school: "清华大学") let student2 = Student(name: "Ben",age: 28,school: "北京大学") let student3 = Student(name: "Tony",age: 38,school: "香港大学") let worker1 = Worker(name: "Tom",factory: "钢厂") let worker2 = Worker(name: "Ben",age: 20,factory: "电厂") 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)") } }
@H_502_1@
@H_502_1@使用@H_502_1@for in@H_502_1@@H_502_1@遍历@H_502_1@people@H_502_1@@H_502_1@数组集合。在循环体中,@H_502_1@@H_502_1@ @H_502_1@letstudent = item as? Student@H_502_1@@H_502_1@@H_502_1@语句使用@H_502_1@as?@H_502_1@@H_502_1@操作符将元素转换为@H_502_1@Student@H_502_1@@H_502_1@类型。如果转换成功,则把元素赋值给@H_502_1@Student@H_502_1@@H_502_1@变量,否则将@H_502_1@nil@H_502_1@@H_502_1@赋值给@H_502_1@Student@H_502_1@@H_502_1@变量,转换成功执行代码。@H_502_1@@H_502_1@
@H_502_1@ @H_502_1@Student school: @H_502_1@清华大学@H_502_1@@H_502_1@
@H_502_1@Student school: @H_502_1@北京大学@H_502_1@@H_502_1@
@H_502_1@Student school: @H_502_1@香港大学@H_502_1@@H_502_1@
@H_502_1@Worker factory: @H_502_1@钢厂@H_502_1@@H_502_1@
@H_502_1@Worker factory: @H_502_1@电厂@H_502_1@@H_502_1@
@H_502_1@@H_502_1@
@H_502_1@as?@H_502_1@@H_502_1@操作符是在不确定是否类型转换能够成功情况下使用,如果成功转换结果是可选类型。如果我们能够确保转换一定成功,可以使用@H_502_1@as!@H_502_1@@H_502_1@操作符在转换的同时进行隐式拆包。@H_502_1@@H_502_1@
@H_502_1@... let people = [student1,worker2] ... let stud1 = people[0] as? Student //people数组的第一个元素 print(stud1) print(stud1!.name) let stud2 = people[1] as! Student //people数组的第二个元素 print(stud2) print(stud2.name)
@H_502_1@
@H_502_1@
@H_502_1@ @H_502_1@Optional(Student)@H_502_1@
@H_502_1@Student@H_502_1@
@H_502_1@代码中@H_502_1@people@H_502_1@@H_502_1@数组的第一个元素,使用@H_502_1@as?@H_502_1@@H_502_1@操作符转换为@H_502_1@Student@H_502_1@@H_502_1@类型,转换成功为@H_502_1@Optional(Student)@H_502_1@@H_502_1@,即@H_502_1@Student@H_502_1@@H_502_1@可选类型。@H_502_1@@H_502_1@
@H_502_1@代码中@H_502_1@people@H_502_1@@H_502_1@数组的第二个元素,使用@H_502_1@as!@H_502_1@@H_502_1@操作符转换为@H_502_1@Student@H_502_1@@H_502_1@类型,转换成功为@H_502_1@Student@H_502_1@@H_502_1@类型实例,而非@H_502_1@Student@H_502_1@@H_502_1@可选类型。@H_502_1@@H_502_1@
@H_502_1@ @H_502_1@欢迎关注关东升新浪微博@H_502_1@@tony_@H_502_1@关东升。@H_502_1@
@H_502_1@关注智捷课堂微信公共平台,了解最新技术文章、图书、教程信息@H_502_1@
@H_502_1@@H_502_1@@H_502_1@@H_502_1@
@H_502_1@更多精品@H_502_1@iOS@H_502_1@、@H_502_1@Cocos@H_502_1@、移动设计课程请关注智捷课堂官方网站:@H_502_1@http://www.zhijieketang.com@H_502_1@
@H_502_1@智捷课堂论坛网站:@H_502_1@http://51work6.com/forum.php@H_502_1@