《从零开始学Swift》学习笔记(Day48)——类型检查与转换

前端之家收集整理的这篇文章主要介绍了《从零开始学Swift》学习笔记(Day48)——类型检查与转换前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
原创文章,欢迎转载。转载请注明:关东升的博客@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@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@

@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@@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@

@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@

工人人数:@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@

@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@@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@

@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@@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@

示例代码如下:@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@@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@

@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@

猜你在找的Swift相关文章