------ 知之博客 期待与您交流! -------
- 构造函数
构造函数:构造函数是一种特殊的函数,主要用来在创建对象时初始化对象,为对象成员变量设置初始值。
Swift中是支持函数重载的,所有的构造函数命都是init,虽然OC是不支持重载的,但是OC支持构造函数,OC中的构造函数是initWithXXX。
构造函数的作用:分配空间、设置初始值。
二 构造函数的重载
创建一个swift项目,然后创建一个Person类,在Person类中声明属性。
<span style="font-size:12px;">import UIKit
class Person: NSObject {
///姓名
var name: String
///年龄
var age: Int
}</span>
然后Command+B编译一下会报错(错误信息:Class 'Person' has no initializers),错误的原因是因为Swift中的属性分为可选属性和必选属性,如果我们没有加‘?’进行修饰,那么他就是一个必选属性,所谓的必选属性就要在初始化方法里面去给他分配空间和设置初始值。
由于NSObject中虽然有init()这个方法,但是系统里面并没有我们声明的这些属性,子类有需要执行自己的逻辑,所以结合OC的思路我们很容易想到继承之后进行方法的重写。(Swift中重写用override进行修饰)
import UIKit
class Person: NSObject {
var name: String
var age: Int
///重写
override init(){
//步骤1
name = "老王"
age = 13
//步骤2
super.init()
}
}
在这里一定要注意先初始化子类的必选属性,然后在初始化父类,否则系统会报错(错误信息:Property ‘self.name’ not initialized at super.init call),其实还是去系统查找属性去了,但是系统根本没有我们自定义的属性。所以要先初始化子类的必选属性,然后在初始化父类。
在控制器中初始化Person对象,然后打印name、age的值,如下:
<span style="font-size:12px;"> import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let p = Person()
print("name=\(p.name),age=\(p.age)")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}</span>
但是这样执行的结果是一定的,那如何根据我们的设定来改变name、age的值呢?这就引入了构造函数的重载概念,可以根据需求初始化出一个我们需要的对象出来。需要注意的是构造函数不能用override进行修饰,因为系统本身是没有这个方法的。
<span style="font-size:12px;">
import UIKit
class Person: NSObject {
var name: String
var age: Int
///构造函数重载
init(name: String,age: Int) {
self.name = name
self.age = age
super.init()
}
}</span>
在控制器初始化person对象,就只能调用我们重载的构造函数了,
因为如果重载了构造函数,并没有重写默认的构造函数,系统默认构造函数就不再提供了,默认的init()无法完成分配空间和设置初始值的工作,所以也就不能使用了,当Person再去调用init()的时候就会报错。
<span style="font-size:12px;">
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//初始话person对象
let p = Person(name: "西门庆", age: 22)
print(p.name)
print(p.age)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
</span>
输出结果就是:老王 22.
三 小结
非 Optional 属性,都必须在构造函数中设置初始值,从而保证对象在被实例化的时候,属性都被正确初始化;
在调用父类构造函数之前,必须保证本类的属性都已经完成初始化;
Swift 中的构造函数不用写 func。
《Swift-构造函数(二)》将介绍子类的构造函数。