/*
當重寫父類的指定初始化器時,必須加上override(即使子類的實作是便捷初始化器)
如果子類寫了一個比對父類便捷初始化器的初始化器,不用加上override,因為父類的便捷初始化器永遠不會通過子類直接調用,是以,嚴格來說,子類無法重寫父類的便捷初始化器
便捷初始化器隻能橫向調用,不能被子類調用
*/
class Person{
var age:Int
init(age:Int){
self.age=age
}
convenience init(){
self.init(age:1)
}
}
class Child:Person{
override init(age:Int){
super.init(age:age)
}
}
class Person{
var age:Int
init(age:Int){
self.age=age
}
convenience init(){
self.init(age:1)
}
}
class Child:Person{
var name:String
init(age:Int,name:String){
self.name = name
super.init(age:age)
}
convenience init(){ //省略override
self.init(age:1,name:"sw")
}
}
1.6-自動繼承
/*
1、如果子類沒有自定義任何指定初始化器,它會自動繼承父類所有的指定初始化器
2、如果子類提供了父類所有指定初始化器的實作(要麼通過方式1繼承,要麼重寫)子類自動繼承所有的父類便捷初始化器
3、就算子類添加了更多的便捷初始化器,這些規則仍然适用
4、子類以便捷初始化器的形式重寫父類的指定初始化器,也可以作為滿足規則2的一部分
*/
class Person{
var age:Int
var name:String
init(age:Int,name:String){
self.name=name
self.age=age
}
init(age:Int){
self.age=age
self.name="sw"
}
}
class Child:Person{
}
var c1=Child(age:1)
var c2=Child(age:1,name: "Maria")
1.7-required
/*
用required修飾指定初始化器,表明其所有子類都必須實作該初始化器(通過繼承或者重寫實作)
如果子類重寫了required初始化器,也必須加上required,不用加override
*/
//'required' modifier must be present on all overrides of a required initializer
required init(age:Int){
//…
}
class Child:Person{
init(age:Int){
super.age=age
}
}
class Person{
init(age:Int){
}
required init(){
}
}
class Child:Person{
required init(){
super.init()
}
}
1.8-屬性觀察器
/*
父類的屬性在它自己的初始化器中指派不會觸發屬性觀察器,但在子類的初始化器中指派會觸發屬性觀察器
*/
class Person{
var age:Int{
willSet{
print("Person.willSet",newValue)
}
didSet{
print("Person.didSet",oldValue,age)
}
}
init() {
self.age=1
}
}
class Child:Person{
override init(){
super.init()
self.age=18
}
}
var c = Child()//子類觸發了屬性觀察器,父類init()不會觸發
Person.willSet 18
Person.didSet 1 18
1.9-可失敗初始化器
/*
類、結構體、枚舉都可以使用init?定義可失敗初始化器
之前接觸過的可失敗初始化器
不允許同時定義參數标簽、參數個數、參數類型相同的可失敗初始化器和非可失敗初始化器
可以用init!定義隐式解包的可失敗初始化器
可失敗初始化器可以調用非可失敗初始化器,非可失敗初始化器調用可失敗初始化器需要進行解包
如果初始化器調用一個可失敗初始化器導緻初始化失敗,那麼整個初始化過程都失敗,并且之後的代碼都停止執行
可以用一個非可失敗初始化器重寫一個可失敗初始化器,但反過來是不行的
*/
class Person{
var name:String
init?(name:String){
if name.isEmpty{
return nil
}
self.name=name
}
convenience init?(){
self.init(name:"") //一旦失敗初始化失敗
self.name="sw"
//...
}
}
var p = Person()
print(p.name) //報錯
//枚舉、類型轉換器就是可失敗初始化器
@inlinable public init?(_ description: String)
var test = Int("t")
print(test)
nil
enum Test:Int {
case test1,test2
}
var t = Test(rawValue: 3)
print(t)
nil
1.10-反初始化器
/*
析構函數
deinit叫做反初始化器,類似于C++的析構函數、OC中的dealloc方法;當類的執行個體對象被釋放記憶體時,就會調用執行個體對象的deinit方法
deinit不接受任何參數,不能寫小括号,不能自行調用
父類的deinit能被子類繼承
子類的deinit實作執行完畢後會調用父類的deinit
*/
class Person{
deinit {
print("Person class dead.")
}
}
var p:Person?=Person()
p=nil
Person class dead.