三十 Swift5 0之 構造方法 二

2021-07-30 23:20:07 字數 4081 閱讀 3294

/*

繼承與構造方法:

指定構造與便利構造方法

*/class

person

// 如果是值型別沒問題, 稱之為構造器**

// 但如果是引用型別會報錯, 需要在前面加上convenience關鍵字

// 被convenience關鍵字修飾的構造方法稱之為便利構造器, 通過呼叫其它構造方法來初始化

// 反而言之, 便利構造器中一定是呼叫其它構造方法初始化的, 一定要出現self.init

convenience

init()

// 類可以擁有多個構造方法

init

(name:

string

)convenience

init

(age:

int)

// 便利構造器不能和指定構造器同名

// convenience init(name:string)

// }/*

派生類的構造方法

*/class

man// 便利構造方法

convenience

init()

}class

superman

:man}/*

構造器間的呼叫規則

>指定構造器必須呼叫其直接父類的"指定構造器"

>便利構造器必須呼叫同類中的其它構造器(指定或便利)

>便利構造器必須最終以呼叫乙個指定構造器結束(無論呼叫的時指定還是便利, 最終肯定會呼叫乙個指定構造器)

*指定構造器總是向上**(父類)

*便利構造器總是橫向**(當前類)

*/class

man2

// 便利構造方法

convenience

init()

}class

superman2

:man2

convenience

init()

convenience

init

(name:

string

, age:

int)}/*

兩段式構造- 構造過程可以劃分為兩個階段

1.確保當前類和父類所有儲存屬性都被初始化

2.做一些其它初始化操作

> 好處: 1.可以防止屬性在被初始化之前訪問, 2.可以防止屬性被另外乙個構造器意外賦值

注意:構造器的初始化永遠是在所有類的第一階段初始化完畢之後才會開始第二階段

編譯器安全檢查:

1.必須先初始化子類特有屬性, 再向上**父類指定構造方法初始化父類屬性

2.只能在呼叫完父類指定構造器後才能訪問父類屬性

3.在遍歷構造器中, 必須先呼叫同類其它構造方法後才能訪問屬性

4.第一階段完成前不能訪問父類屬性/也不能引用self和呼叫任何例項方法

*/class

man3

// 便利構造方法

convenience

init()

}class

superman3

:man3

// 對父類引入的屬性進行初始化

super

.init

(name:

"gezi"

)print

("superman第二階段開始"

)if age >30}

}class

monkeyman

:superman3}}

var m =

monkeyman

(height:20)

/*重寫指定構造方法: 子類的構造方法和父類的一模一樣

*/class

man4

}class

superman4

:man4

// 如果子類中的構造器和父類一模一樣, 必須加上override關鍵字, 表示重寫父類方法

// 在老版本的swift語言中是不需要override關鍵字的, 新版本才推出的

// override init(name:string)

// 將父類的指定構造器重寫成乙個便利構造器, 也必須加上override關鍵字, 表示重寫父類方法

convenience

override

init

(name:

string)}

/*便利構造方法不存在重寫

*/class

man5

convenience

init()

}class

superman5

:man5

// swift中便利構造方法不存在重寫, 如果加上override關鍵字, 系統會去查詢父類中有沒有和便利構造方法一樣的指定構造方法, 有舊不報錯, 沒有就報錯

// 為什麼便利構造器不能重寫呢? 因為便利構造器只能橫向**, 只能呼叫當前類的其它構造方法或指定方法, 不可能呼叫super. 所以不存在重寫

// 也就是說子類的便利構造方法不能直接訪問父類的便利構造方法, 所以不存在重寫的概念

convenience

init()

}// 早期版本中如果字元類中有同名便利構造器會報錯

var sm =

superman5()

/*構造方法的自動繼承

> 如果子類中沒有定義任何構造器, 且子類中所有的儲存屬性都有預設值, 會繼承父類中所有的構造方法(包括便利構造器)

> 如果子類中只是重寫了父類中的某些指定構造器, 不管子類中的儲存屬性是否有預設值, 都不會繼承父類中的其它構造方法

>如果子類重寫了父類中所有的指定構造器, 不管子類中的儲存屬性是否有預設值, 都會同時繼承父類中的所有便利方法

*/class

person6

init

(name:

string

)convenience

init()

}class

superman6

:person6

override

init

(name:

string

, age:

int)

override

init

(name:

string)}

// 如果子類中沒有定義任何構造器, 且子類中所有的儲存屬性都有預設值, 會繼承父類中所有的構造方法(包括便利構造器)

// 父類的儲存屬性是由父類的構造器初始化, 子類的儲存屬性是由預設值初始化的

//var sm = superman(name: "gezi", age: 30)

//var sm = superman(name: "zs")

//var sm = superman()

//print(sm.height)

// 如果子類中只是重寫了父類中的某些指定構造器, 不管子類中的儲存屬性是否有預設值, 都不會繼承父類中的其它構造方法

//var sm = superman(height: 188.0)

// 如果子類重寫了父類中所有的指定構造器, 不管子類中的儲存屬性是否有預設值, 都會同時繼承父類中的所有便利方法

var sm6 =

superman6()

/*必須構造器:

只要在構造方法的前面加上乙個required關鍵字, 那麼所有的子類(後續子類)只要定義了構造方法都必須實現該構造方法

*/class

person7

}class

superman7

:person7

// 1.如果子類自定義了構造器, 就必須重寫"必須構造器"

// 因為如果子類沒有自定義任何構造器, 缺省會繼承父類構造器, 所以不用重寫

// 2.重寫必須構造器不用加override關鍵字, 因為系統看到required關鍵字就會自動檢視父類

// 為什麼重寫了還需要加上required關鍵字, 因為所有後續子類都必須重寫

required

init

(name:

string)}

var sm7 =

superman7

(name:

"gezi"

)

四 Swift 5 0之 Bool型別

全系列導航 swift5.0 系列部落格索引 c語言和oc並沒有真正的bool型別 c語言的bool型別非0即真 oc語言的bool型別是typedef signed char bool swift引入了真正的bool型別 bool true false let isopen bool true l...

六 Swift5 0之 可選值

全系列導航 swift5.0 系列部落格索引 可選值 optionals有兩種狀態 1.有值 2.沒有值,沒有值就是nil 有值 var optvalue1 int?9 沒有值 var optvalue2 int?var optvalue3 int?nil 可選值可以利用if語句來進行判斷 var ...

十一 Swift5 0之 while 用法

全系列導航 swift5.0 系列部落格索引 while迴圈 格式 while 迴圈保持條件 oc int i 0 int sum 0 while i 10 while i 10 sum i nslog d sum 如果只有一條指令while後面的大括號可以省略 swift 0.while後的圓括號...