指定构造方法和便利构造方法
/*
1、指定构造方法和便利构造方法(Designated Initializer and Convenience Initializers)
便利构造:类类型(针对类class)
*/
print("1、指定构造方法和便利构造方法")
class AB {
var a:Int
var b:Int
//指定构造方法,不允许出现构造代理器,self.init(...)
init(a:Int,b:Int) {
self.a = a
self.b = b
print("class AB init")
}
//便利构造方法 -- 一定是通过调用其他的构造方法来实现初始化,self.init(...)
convenience init(a:Int) {
// self.a = a
// b = 0
self.init(a:a,b:0)
}
//便利构造方法也可以通过调用其他的 便利构造方法实现初始化
convenience init() {
self.init(a:0)
}
}
/*
2、派生类的构造方法
*/
/*
3、构造器链--指定构造器和便利构造器之间的调用规则
(1)指定构造器必须调用其直接父类的指定构造器
(2)便利构造器必须调用同类中定义的其他构造器(指定/便利)
(3)便利构造器最终以调用一个指定构造器结束
指定构造器总是向上代理
便利构造器总是横向代理
*/
print("\n2、派生类的构造方法")
class CD: AB {
var c:Int
var d:Int
//构造方法默认是不会被继承,基类的存储属性只能通过基类的构造方法来初始化
//派生类引入的存储属性要先被初始化,然后再调用父类的构造方法对父类的属性进行初始化
//只能通过调用父类的指定构造方法来对父类的属性进行初始化,不能通过便利构造方法
init(c:Int,d:Int) {
self.c = c
self.d = d
super.init(a: 0, b: 0)
}
//便利构造器,只能通过调用本类中的构造器完成初始化,不允许出现super.init()
convenience init(a:Int,b:Int,c:Int,d:Int) {
self.init(c:c,d:d)
}
}
/*
4、两段式构造--构造过程分为两个阶段
(1)第一阶段:确保所有存储属性都初始化完毕
(2)第二阶段:对父类存储属性作进一步处理
可以防止属性在被初始化之前访问,也可以防止属性被另外一个构造器意外赋值
*/
print("\n4、两段式构造")
/*
5、派生类构造方法定义时的编译器安全性检查
(1)首先应该将派生类引入的存储属性初始化,然后再向上代理父类的指定构造方法
(2)首先调用父类中的指定构造器实现父类中属性的初始化之后,才可以访问父类中的属性
(3)在编写便利构造器方法时,首先要调用同类中的其他构造方法,才可以访问任意属性
(4)在第一阶段完成之前,不能调用任何实例方法,不能访问父类中定义的任何存储属性,也不能使用self
*/
class A{
var a:Int
init(a:Int) {
self.a = a
}
}
class B:A{
var b:Int
init(a:Int,b:Int) {
//派生类引入的属性进行初始化
print("类B第一阶段初始化开始")
self.b = b
//从父类的指定构造器方法对父类属性进行初始化
super.init(a: a)
print("类B第二阶段初始化开始")
}
}
class C:B{
var c:Int
init(a:Int,b:Int,c:Int) {
//派生类引入的属性进行初始化
print("类C第一阶段初始化开始")
self.c = c
//从父类的指定构造器方法对父类属性进行初始化
super.init(a: a,b: b)
print("类C第二阶段初始化开始")
}
}
class D:C{
var d:Int
init(a:Int,b:Int,c:Int,d:Int) {
//派生类引入的属性进行初始化
print("类D第一阶段初始化开始")
self.d = d
//从父类的指定构造器方法对父类属性进行初始化
super.init(a: a,b: b,c: c)
print("类D第二阶段初始化开始")
}
convenience init(){
self.init(a:0,b:0,c:0,d:0)
a = 1
b = 2
c = 3
d = 4
}
}
var d = D(a:0,b:0,c:0,d:0)
/*
6、重写指定构造方法(子类中构造方法与父类中构造方法的参数列表一模一样)
便利构造方法不存在重写
*/
print("\n6、重写指定构造方法")
class Human {
let name:String
var age:Int
init(name:String,age:Int) {
self.name = name
self.age = age
}
}
class Woman: Human {
var haveBaby:Bool = false
// //派生类中定义一个构造方法,它跟父类中的某个指定构造方法一样
// override init(name: String, age: Int) {
// haveBaby = false
// super.init(name: name, age: age)
// }
init(name: String, age: Int,haveBaby:Bool) {
self.haveBaby = haveBaby
super.init(name: name, age: age)
}
convenience override init(name: String, age: Int) {
self.init(name: name, age: age,haveBaby:false)
}
}
/*
7、构造器的自动继承
(1)如果子类中没有定义任何的构造方法,且子类中所有的存储属性都有默认缺省值,子类会自动继承父类中所有的构造方法(包括便利构造方法)
(2)如果子类中只是重写了父类中的某些(不是全部)指定构造方法,不管子类中的存储属性是否有缺省值,都不会继承父类中的其他构造方法
(3)如果子类中重写了父类中所有的指定构造方法,不管子类中存储属性是否有缺省值,都同时会继承父类中所有的便利构造方法
*/
print("\n7、构造器的自动继承")
class XY {
var x:Int
var y:Int
init(x:Int,y:Int) {
self.x = x
self.y = y
}
init(x:Int) {
self.x = x
self.y = 0
}
convenience init(){
self.init(x:0,y:0)
}
}
class XYZ: XY {
var z:Int = 0
}
var xyz = XYZ()
var xyz1 = XYZ(x:10)
var xyz2 = XYZ(x:5,y:5)
/*
8、必须构造器(构造方法所属类的后续子类必须也得实现这个构造方法)
*/
print("\n8、必须构造器")
class Require{
var a:Int
//required 关键字
required init(){
a = 0
}
}
class ChildOfRequire:Require{
var sub:Int
init(sub:Int){
self.sub = sub
super.init()
}
required init() {
sub = 0
}
}