/* 构造函数 init
init函数,没有返回值,不能用func修饰,不能通过实例调用init,只能用init调用其他重载的init。
✨关于override的特殊规定,普通方法必须override,指定构造必须override,便利构造不能写override修饰符。
当override一个required的构造函数时,不需要写override。override一个required的构造时,所有子类都需要加required。
required构造函数,可以通过继承获得,而不需要一定去重写。但是只要写了,必须加required。
另外,required只能用于init函数。
✨在定义了自己的指定init后,默认的init就没有啦
init函数结构体,枚举都可以有。但是deinit析构函数只能在类中才能有。
实例创建前,必须对所有的stored property进行初始化,这个可以在定义变量的时候赋初值
也可以在init函数中进行。
如果没有特殊需求,请在变量定义的时候初始化。在init中初始化的好处是,
1)可以在不同的重载函数init中初始化不同的值
2)在类继承的时候可以对初始化值进行修改。
3)另外,在定义时初始化 和 init中初始化都不会触发property observer
4)在初始化函数中可以对const的变量进行重新赋初值。
在init中调用其他的self.init(必须加self)函数时,称为initializer delegation初始化代理
✨✨✨值类型的构造函数之间没有特殊规定。(结构体等),但是类中的init函数分为指定构造和便利构造。
类中因为多了继承的原因,为了保证所有的属性都被初始化,特做了如下规定:
构造其分为 Designated(指定,特定) initializer,convenience initializer:
1.若有父类,并且子类实现了指定构造器,必须在指定构造器中的初始化阶段1(所有子类属性初始化,见官网定义)最后调用super.init()
2.便利构造函数必须调用同一类中定义的其他构造器。包含指定构造器和便利构造器(该构造器调用了指定构造器)。
3.init函数可以调用instanceMethod,也可以对属性赋值,但是不可以在初始化阶段1(所有的变量都被初始化)之前。
✨✨总则:指定构造器必须向上代理。便利构造器必须横向代理(必须调用一个指定构造器结束)。
关于子类的继承(自己的理解):
1.在初始化的时候父类的属性尽量不要在子类中直接修改,当然在初始化阶段1后是可以修改的。
尽量调用super.init(var1:xx, var2:xx),反过来说如果在子类中直接初始化,继承的意义就不大了。
2.如果子类没有定义designated init,则子类继承所有父类的指定构造器,
如果定义了任意一个指定构造器,则所有的指定构造器将不会被继承✨✨。
3.如果通过继承或者自己定义了父类的所有指定构造器,则子类会自动继承父类所有的便利构造器。
(注意便利构造器一定会调用指定构造器,这时调用的都是当前子类中的指定构造器)
反过来说,如果任何一个指定构造器没有在子类中被重新定义,则所有便利构造器不会被继承。
4.可以用reqired修饰符来要求子类必须实现某个init(类似C++的Interface),子类中必须要有required的init
可以重新定义父类中的required init,也可以通过继承获得。
5.final一下,就不会在子类中被override,
requried只能用于构造init,而final可以用于属性,除构造函数的任意函数,以及整个类
6.注意final lazy required前面在新版本中都不需要@,在OC中为了减少和C的冲突,OC的关键字都带@
*/
struct RectStruct
{
var width:Int
var height:Int
init()//在前面加func会报错
{
width = 1 //类中的成员变量,初始化阶段1之后,所有属性必须被进行初始化,否则报错。
height = 2
}
init(iw:Int, ih:Int)
{
self.init()//注意valueType的init时没有讲究的,但是类的就比较复杂。
}
}
//var s = RectStruct(width:3, height:4) //写了自己的初始化函数后,默认的初始化函数不可用。
class Animal
{
var name:String
init(name:String)
{
self.name = name
println("In class Animal designated init")
}
init(id:Int)
{
self.name ="default name!"
}
// convenience init
convenience init()
{
self.init(name:"Animal") //convenience init必须调用一个designated init
println("In Animal convenience init")
}
}
class EmptyBird :Animal
{
}
var b = EmptyBird()
//In class Animal designated init
//In Animal convenience init
//一个空的子类会完全继承父类的指定构造器和便利构造器
class RealBird :Animal
{
var canfly:Bool
//var canrun:Bool = true 如果定义了这个属性,则要么在所有的designated init中赋初值
//要么在定义时赋初值,否则会报错。
init(name:String, canfly:Bool)
{
self.canfly = canfly
// self.instanceMethod() instanceMethod不可以在初始化阶段1(所有的变量都被初始化),之前调用。
super.init(name:name)//初始化阶段1的最后,不能放在self.canfly赋值的前面。
println("In RealBird designated init")
self.instanceMethod()
}
func instanceMethod()
{
self.canfly =true
}
}
// var realbird = RealBird()
var realbird =RealBird(name:"maque", canfly:true)
//var realbird2 = RealBird(id:3) 如果子类中有一个指定构造函数,则父类中的指定构造函数不会被继承。
class NoDesignatedInit:Animal
{
convenience init(test:Int)
{
self.init(id:3) //如果子类没有定义designated init,则子类继承所有父类的指定构造器
}
}
class OlnyPartDesignatedInit:Animal
{
var myvar:Int
init(id:Int)
{
//在指定构造器中将所有的子类stored属性初始化完,方可调用完父类进行初始化后
myvar = 3
super.init(id:id)
//将所有的stored属性初始化一遍(初始化阶段1)后,可以进行再次赋值等其他操作。
self.name = "OlnyPartDesignatedInit"
}
}
//只继承一个指定构造器,且没有继承,便利构造器调用的init(name:String)
//便利构造器无法被继承。
//ERROR var bird3 = OlnyPartDesignatedInit()
class OlnyPartDesignatedInit2:Animal
{
init(name:String)
{
super.init(name:name)
println("In class Animal designated init")
}
}
//只继承一个指定构造器,且继承了便利构造器调用的init(name:String)
//便利构造器无法被继承。
//ERROR var bird3 = OlnyPartDesignatedInit2()
class AllDesignatedInit:Animal
{
init(name:String)
{
super.init(name:name)
println("In class Animal designated init")
}
init(id:Int)
{
super.init(id:id)
self.name ="default name!"
}
}
//结论,如果想让任何一个便利构造器被继承,则必须实现所有的指定构造器,否则不可以继承便利构造器。
var bird4 = AllDesignatedInit()
class RequiredClass
{
var memInt:Int
required init(myInt:Int)
{
memInt = myInt
}
required convenience init()
{
self.init(myInt:3)
}
}
class SubClass : RequiredClass
{
//required的构造函数可以通过继承来获得,
//如果继承不到的情况,就必须写。比如只定义了部分指定构造,便利构造不会被默认继承
//这时需要自己添加required的部分,添加时子类也要加上required的修饰。
}
//《完》