類的構造函數
構造函數的介紹
- 構造函數類似於OC中的初始化方法:init方法
- 默認情況下載創建一個類時,必然會調用一個構造函數
- 即便是沒有編寫任何構造函數,編譯器也會提供一個默認的構造函數。
- 如果是繼承自NSObject,可以對父類的構造函數進行重寫
構造函數的基本使用
構造函數的基本使用
- 類的屬性必須有值
- 如果不是在定義時初始化值,可以在構造函數中賦值
class Person: NSObject { var name : String var age : Int // 重寫了NSObject(父類)的構造方法 override init() { name = "" age = 0 } } // 創建一個Person對象 let p = Person()
初始化時給屬性賦值
- 很多時候,我們在創建一個對象時就會給屬性賦值
- 可以自定義構造函數
- 注意:如果自定義了構造函數,會覆蓋init()方法.即不在有默認的構造函數
class Person: NSObject { var name : String var age : Int // 自定義構造函數,會覆蓋init()函數 init(name : String, age : Int) { self.name = name self.age = age } } // 創建一個Person對象 let p = Person(name: "why", age: 18)
字典轉模型(初始化時傳入字典)
- 真實創建對象時,更多的是將字典轉成模型
- 注意:
- 去字典中取出的是NSObject,任意類型.
- 可以通過as!轉成需要的類型,再賦值(不可以直接賦值)
class Person: NSObject { var name : String var age : Int // 自定義構造函數,會覆蓋init()函數 init(dict : [String : NSObject]) { name = dict["name"] as! String age = dict["age"] as! Int } } // 創建一個Person對象 let dict = ["name" : "why", "age" : 18] let p = Person(dict: dict)
字典轉模型(利用KVC轉化)
- 利用KVC字典轉模型會更加方便
- 注意:
- KVC並不能保證會給所有的屬性賦值
- 因此屬性需要有默認值
- 基本數據類型默認值設置為0
- 對象或者結構體類型定義為可選類型即可(可選類型沒有賦值前為nil)
class Person: NSObject { // 結構體或者類的類型,必須是可選類型.因為不能保證一定會賦值 var name : String? // 基本數據類型不能是可選類型,否則KVC無法轉化 var age : Int = 0 // 自定義構造函數,會覆蓋init()函數 init(dict : [String : NSObject]) { // 必須先初始化對象 super.init() // 調用對象的KVC方法字典轉模型 setValuesForKeysWithDictionary(dict) } } // 創建一個Person對象 let dict = ["name" : "why", "age" : 18] let p = Person(dict: dict)
import UIKit class Person: NSObject { //1:定義類的實例屬性,必須保證初始化有默認值,或在初始化中給屬性賦值,基本數據類型默認值為0,對象或是結構體默認的值為可選類型,可選類型在沒有賦值之前為nil var name : String? var age : Int = 0 //2:重寫類的init方法,必須加override override init() { // 在構造函數中,如果沒有明確super.init(),那么系統會幫助調用super.init() // super.init() print("------") } //3:自定義構造函數:帶參數 init(name : String, age : Int) { //給類的實例屬性復制的時候,可以直接賦值,不用self,當兩個名字不同的時候,可以用self來區分不同的值 self.name = name self.age = age } //4:字典轉模型:AnyObject為任意類型,可為nil,也可以不為nil,dic["name"],取出的類型為AnyObject類型,而屬性name為可選類型,是兩個完全不相同的類型,所以不能去賦值。要進行類型轉化:as? 最終轉成的類型是一個可選類型,as! 最終轉成的類型是一個確定的類型 init(dic : [String : AnyObject]) { let tempName = dic["name"] // tempName是一個AnyObject類型?,轉成String? // as? 最終轉成的類型是一個可選類型 // as! 最終轉成的類型是一個確定的類型 name = tempName as? String//將AnyObject類型的tempName常量轉換為可選類型與name類型相同,所以可以給name去賦值 /* let tempAge = dict["age"] let tempAge1 = tempAge as? Int if tempAge1 != nil { age = tempAge1! } */ //dic["age"]為AnyObject類型,將此類型轉換為與age類型相同才能賦值,先轉換為可選類型dic["age"] as? Int,有可能取出的age為nil,就會出現錯誤,所以進行可選綁定,如果不為nil,強制解包賦值 if let tempAge = dic["age"] as? Int { age = tempAge } } init(dict : [String : AnyObject]) { super.init()//調用此方法可以初始化一個類實例 setValuesForKeys(dict)//調用類實例的方法,可以直接寫,不用self.去調用 } //重寫類中的方法必須加上override override func setValue(_ value: Any?, forUndefinedKey key: String) { } } let p = Person()//初始化對象 let p1 = Person(name: "why", age: 18) print(p1.age) print(p1.name) //as AnyObject:因為規定了字典的value值類型為AnyObject類型,所以在外部傳遞參數的時候,要將參數轉為相同類型as AnyObject就是轉換為AnyObject的類型 let p2 = Person(dict: ["name" : "why" as AnyObject, "height" : 1.88 as AnyObject, "age" : 18 as AnyObject]) print(p2.age) print(p2.name)