1.1 构造函数的定义
- 就是 类 的构造函数. 在OC中 凡是以 init 开头的函数, 我们都称之为构造函数,在声明构造函数的时候,不带参数的一般直接声明为"-(id)init",带参数的一般声明为"-(id)initWith...".
- Swift中 只有 init方法.
/*
OC 中初始化一个类 OC alloc init
开辟内存空间 给其类身上的成员变量初始化
Swift Swift ()
再次提醒: 常量可选值没有什么意义, 并且没有默认值, 声明的时候就要为其赋值.
注意: 类的 属性 为一个 必选值的时候, 不是在声明的时候赋值, 就是在 init方法中实例化赋值.
*/
1.2自定义Person类, 实现构造函数
class Person: NSObject {
// 声明 Person类的名称, 年龄属性; 因为外界可能会多次赋值, 所以这里使用var来声明
var name: String
var age: Int
// override 关键字: 前面已经说过了, 这是对父类已有方法的重写
override init() {
/*
思考: 类中的属性为必选值的时候, 不是声明的时候赋值,就是在init方法中实例化的时候赋值, 那应该在super之前还是之后呢?????
答案: 应放在super之前
*/
// 1. 在super之前. 表示先把自己要做的事情(为自己的属性赋值)做完, 然后再去找父类, 完成当前类的实例化
name = "老张"
age = 18
/* 注意:
1. 在Swift中, 系统会帮助你隐式调用 super.init()
2. 虽然会隐式帮助你调用, 但是我们通常也都要自己写上, 这样方便阅读,理解
*/
super.init()
// 2. 在super之后是错误的. 因为先进行了super操作, 完成了类的实例化, 这时候却发现该类的成员变量都没有初始化赋值, 所以会造成报错: Property 'self.name' not initialized at super.init call
// name = "老张"
// age = 18
}
}
思考: 在自定义Person类的过程中, 发现了一个定义, 叫做 '类的实例化完成', 那么什么时候代表一个类实例化完成了呢???
分析: 还是以Person类为例, 当外界调用Person()的时候, 也就是开始了类的实例化, 当做完自己该做的事情后(为其成员变量赋值等操作), 才去告诉自己的父类(super操作), 找到父类之后, 才算完成当前类的实例化, 如果没有父类, 也就无所谓了.
1.3 外界对自定义的Person类的使用
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
/* 注意:
1. 一般来说, 不需要导入类的头文件, 全局共享.
2. pods文件, 必须导入头文件
*/
let p = Person()
print(p.name, p.age)
// 结果:老张 18
}
}
1.4 子类构造函数的定义(自定义Student类, 继承于Person类)
需求分析: Student类 继承于 Person类, 并且拥有自己的学号属性 no, 外界初始化Student类并打印信息
通过断点, 调用堆栈查看方法调用顺序, 自下往上看!!!!
这样能更好的理解整个类的实例化过程. image.png
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let s = Student()
print(s.name, s.age, s.no)
// 结果: 老张 18 7
}
}
网友评论