1 初始化函数的两段式构造
(1)第一段:基本构造-----为子类属性及父类属性赋值
(I)父类属性只能通过父类的初始化函数赋值
(II)应该先给子类属性赋值,再调用super.init()方法对父类属性赋值
(2)第二段:进一步完善-----调用super.init()方法后,才可以使用self进行其他的操作
class Person { var name: String var age: Int init(name: String, age: Int) { self.name = name self.age = age } } class Student: Person { var classes: String init(name: String, age: Int, classes: String) { // 基本构造(先对自己的属性赋值,再调用父类初始化函数) self.classes = classes super.init(name: name, age: age) // 进一步完善 self.age += 5 } }
2 指定的(designed)初始化函数、便利的(convenience)初始化函数
(1)指定的初始化函数只能调用父类指定的初始化函数
(2)便利的初始化函数只能调用自己的初始化函数,而不能调用父类的初始化函数。另外便利的初始化函数是不能被子类重写或从子类中以super的方式调用的。
class Person { var name: String var age: Int init(name: String, age: Int) { self.name = name self.age = age } convenience init(name: String) { self.init(name: name, age: 18) } convenience init(firstName: String, lastName: String) { // 只能调用自己的初始化函数 self.init(name: firstName + " " + lastName)
} }
// 下面这个初始化函数是不正确的。因为便利构造函数最终都得调用指定初始化函数来完成初始化过程。在初始化函数未完成时,是不可以使用self来操作的。
convenience init(firstName: String, lastName: String) {
self.name = firstName + " " + lastName
self.age = 18
} class Student: Person { var classes: String init(name: String, age: Int, classes: String) { // 基本构造 self.classes = classes super.init(name: name, age: age) // 进一步完善 self.age += 5 } convenience init(name: String) { let age = 18 let classes = "1" // 只能调用自己的 指定的初始化函数 self.init(name: name, age: age, classes: classes) } }
3 子类构造函数的继承原则
(1)如果子类没有实现父类的任何指定构造函数,则自动继承父类所有的构造函数;
(2)如果子类实现了父类的全部指定构造函数,则自动继承父类所有的便利构造函数;
(3)如果子类写了自己的构造函数,则就不能再继承父类的构造函数。
4 required构造函数
自己创建了一个类,你希望继承它的所有自类都必须实现这个函数,只需要在这个函数前面添加required关键字即可。这样子类继承这个方法时,不需要写override关键字,而是使用required关键字。
class Person { var name: String var age: Int required init(name: String, age: Int) { self.name = name self.age = age } } class Student: Person { var classes: String
// 如果自己写了构造函数,就不能继承父类的构造函数。而父类有一个required的构造函数,因此必须实现这个构造函数。 init(name: String, age: Int, classes: String) { self.classes = classes super.init(name: name, age: age) } //convenience required、required convenience 都可以 convenience required init(name: String, age: Int) { self.init(name: name, age: age, classes: "1") } } //没有实现父类任何一个指定构造函数,默认是继承父类所有的指定构造函数的
class Teacher: Person {
}
let student = Student(name: "Tom", age: 20) let teacher = Teacher(name: "Lily", age: 40)