构造方法内容会多一些,涉及Swift中构造的一些规则与概念。这次写了7个Person来复习,外加名人XiaoMing。
Mark:Playground真是个好东西,特别练习写Swift时,实时显示真是大赞!
一、继承与重写, 防止重写
1.1 基类, 不继承任何类. Swift不想OC或者Java中继承自Object类.定义一个类,不继承任何类,该类就是基类.
class Person1{ //这个Person1就是基类 func eat(){ println("eat a pig!") } }
1.2 继承. Swift为单继承
class XiaoMing1 : Person1{ var name = "xiaoming" }
1.3 重写. 必须加关键字override. (OC,Java中是不必加的)
class XiaoHong1 : Person1{ override func eat() { super.eat(); //可以用super来调用父类中的属性与方法 println("xiaohong eat a pig") } } var xh = XiaoHong1() xh.eat()
1.4 重写属性(存储属性与计算属性)
可以用get/set/willSet/didSet进行属性重写class Person2{ var name:String{ //计算属性 set{ println("Person2 set") } get{ return "Person2" } } let age: Int = 10 //常量存储属性 var height:Int = 175 //变量存储属性 } class XiaoMing2 : Person2{ override var name:String{ set{ super.name = newValue //将父类的值设置为新值 println("XiaoMing2 set") } get{ return "XiaoMing2" } } override var age : Int{ //如果父属性是var的话, 必须有get和set get{ println(super.age) return 20 } } override var height :Int{ //重写观察属性: 继承来的常量存储属性,只读计算属性不能添加观察器. didSet{ //注意有didSet,willSet的地方是不能出现get/set的 println("didset----\(oldValue)") } willSet{ println("willSet----\(newValue)") } } } var xm2 = XiaoMing2() xm2.name = "XM2" println(xm2.age) xm2.height = 10
1.5 防止重写(final). 与Java一样
//可将final写在属性/方法/类等前面 class Person3{ final var name = "Person3" } class XiaoMing3{ //override var name ...//这样会报错 }
Swift中的构造器无返回值(OC中是返回id的), 它的主要任务是保证新实例在第一次使用前完成正确的初始化工作.
init() , 可以重载
2.1 默认构造器与带参数构造器, 继承器的重载
class Person4{ var name : String //必须初始化, 或者在构造函数中初始化 //默认, 不带参数 init(){ //无返回值 name = "xuneng" } //带参数 init(name :String){ //默认是以参数名作为外部参数名的 self.name = name + "Hello" //和OC中相同, 用self.(Java中用this) } //带可选参数. 可选类型: 可以为空,也可以以后赋值. 初始化为nil var age:Int = 10 init(name :String , age:Int?){ self.name = name self.age = age! //可选参数必须确定有(加!号)才能赋值 } } var p4 = Person4() //默认就是没有括号的 var p4_1 = Person4(name: "xn4545945 ") //参数名作为外部参数名 var p4_2 = Person4(name: "neng", age: 10)
2.1 指定构造器(Designated initializer)与便利构造器(convenience initializer)
2.1.1 指定构造器: 每个类必须至少有一个,用来确保所有值都进行初始化.(会根据父类的继承关系往上调用,完成父类的初始化)
//Person4中的3个构造器都是指定构造器, 都需要进行所有成员变量的初始化
2.1.2 便利构造器(加convenience关键字):辅助性的构造器.可以用来同一个类中的指定构造器,也可以用来创建一个有特定输入的实例
class Person5{ var name : String //必须初始化, 或者在指定构造函数中初始化 init(name :String){ //指定构造器 self.name = name + "Hello" } convenience init(name :String , height:Int){ //便利构造器. 不需要全部初始化成员变量 self.init(name:name) println(height) } } var p5 = Person5(name: "xn4545945", height: 175)
2.2 构造器链(概念): 规范指定构造器与便利构造器间的调用关系.
//1) 规则1: 指定构造器必须调用其父类的指定构造器 //2) 规则2: 便利构造器必须调用同一类中调用的其他构造器 //3) 规则3: 便利构造器必须以调用一个指定构造器结束
一句话总结上面3个规律: 指定构造器是向上调用的,便利构造器是横向调用的.
2.3 两段式构造过程 (概念)
第一个阶段:每个存储型属性通过引入它们的类的构造器来设置初始值。两段式构造过程的使用让构造过程更安全,同时在整个类层级结构中给予了每个类完全的灵活性。
Swift 的两段式构造过程跟 Objective-C中的构造过程类似。最主要的区别在于阶段一,Objective-C 给每一个属性赋值 0或空值(比如说 0 或 nil)。Swift的构造流程则更加灵活,它允许你设置定制的初始值,并自如应对某些属性不能以 0或 nil 作为合法默 认值的情况。
2.4 构造器的继承(概念)
与OC不同, Swift中子类不会默认继承父类的构造器. (但如果满足以下2个条件会自动继承)class Father{ init(){ println("father init") } convenience init(name:String){ self.init(); println("father convenience init") } } class Son:Father{ override init(){ //子类实现了父类的全部指定构造器, 因而会自动继承父类的便利构造器 println("son init") } } var son1 = Son() var son2 = Son(name: "xuneng") //自动继承了父类的便利构造器
2.5 通过闭包和函数来设置属性的默认值
//闭包的一般格式 class SomeClass{ let someProperty : Int = { //整个花括号表示一个闭包 return 0 }() //这个小括号不能丢, 表示立即执行闭包. 并返回值. }1)如果某个存储属性的值需要特别定制, 则可以使用闭包或全局函数类提供默认值.
class Person6{ let name : String = {//可以在闭包里面做一些复杂的初始化工作 let firstName = "xu" let lastName = "neng" return firstName + lastName }() } var p6 = Person6() println(p6.name)
三、析构(反初始化) deinit
在一个类实例被释放之前, 反初始化函数被立即调用
Swift通过ARC来处理实例的内存管理, 与OC一样.
每个类只有一个反初始化函数, 不带任何参数. 且不允许主动调用.
子类继承了父类的反初始化函数(释放顺序类似Java. 先释放子类-->父类)
反初始化话方法能访问该实例的所有属性
class Person7{ var myMoney:Int init(){ myMoney = 10 } deinit{ myMoney = 0 //可以访问类中的变量. 但这句没用. 因为销毁了,成员变量即不存在了 //可以做一些清理工作 } } var p:Person7? = Person7() println(p!.myMoney) p = nil //可选类型才能设置为nil //p!.myMoney //错误, 已设置为nil
参考:
The Swift Programming Language
Apple Dev Center
转载请注明出处:http://blog.csdn.net/xn4545945
原文地址:http://blog.csdn.net/xn4545945/article/details/39491097