構造方法總結一

作用:對實例對象的內容進行初始化
Swift要求類或者結構體中的存儲屬性(非lazy的)在對象構造完畢后要有初始化值

語法:
init(參數列表){
    初始化代碼
}

注意:

  1. Swift中類/結構體/枚舉都需要構造方法
  2. 構造方法的作用僅僅是用于初始化屬性,而不是分配內容,分配內存是系統幫我們做的
  3. 構造方法是隱式調用的,通過 類名稱()形式創建一個對象就會隱式調用init()構造方法
  4. 如果所有的存儲屬性都有默認值,可以不提供構造方法,系統會提供一個隱式的構造方法
  5. 如果存儲屬性可以提供缺省值,那么提倡大家使用設置缺省值的方式,這樣可以簡化代碼(不用自定義狗仔方法,不用寫存儲屬性類型)

不帶參數的構造方法

class Person{
    var name : String = "zx"
    var age : Int
    func description() -> String {
        return "name = \(name) age = \(age)"
    }
    init() {
        print("init")
        age = 3
    }
}

/*
 1.分配內存
 2.初始化name和age
 3.構造方法是隱式調用的
 */
var p = Person()
p.description()//顯示調用

帶參數的構造方法


class Person2{
    var name:String
    var age:Int
    func description() ->String{
        return "name = \(name) age = \(age)"
    }

    /*
     構造方法的內部參數,默認也是外部參數
     構造方法對屬性的順序沒有要求,只要保證對象構造完成時所有存儲屬性被初始化即可
     */
    init(age:Int, name:String)
    {
        self.age = age
        self.name = name
    }

}
//var p2 = Person2(name: "zx", age: 30)
var p3 = Person2(age: 30, name: "zx")

可選屬性與構造方法

class Car{
    let name: String
    init(name:String) {
        self.name = name
    }
}

class Person3{
    let name : String
    var age : Int
    var car : Car?
    
    /*
      可選值存儲屬性可以不再構造方法中初始化,
      也就是說可選值在對象構造完畢后不用初始化
      其實如果不對可選存儲屬性進行初始化, 默認就是nil
    */
    init(age:Int,name:String) {
        self.age = age
        self.name = name
    }
    
    func description() ->String{
        return "name = \(name) age = \(age)"
    }
    
}

結構體構造方法

struct Rect{
    
    var width : Double = 0.0
    var height : Double = 0.0
    
    //系統默認會提供一個類似的方法
    /*
    init(width:Double,height:Double) {
        self.width = width
        self.height = height
    }
    
    init() {
        self.width = 0.0
        self.height = 0.0
    }
    */
    
}
var r = Rect()
//var r = Rect(width: 1.0, heigth: 1.0)

/*
 注意: 
 1.在類中默認是沒有逐一構造器的
 2.如果在結構體中自定義了構造方法, 那么系統不會生成默認的逐一構造器
 3.如果給存儲屬性提供了缺省值, 系統還是會提供默認的逐一構造器
   var r = Rect(width: 1.0, heigth: 1.0)
 4.如果給存儲屬性提供了缺省值, 可以使用不帶參數的方法初始化結構體
 */

"值類型"的構造器代理


/*
 構造器代理: 構造方法之間的相互調用
 構造方法可以調用其他構造方法來完成實例的構造, 稱之為構造器代理
 好處: 減少構造方法之間的重復代碼
 */
struct Rect2 {
    var width:Double
    var height:Double
    
    init(width:Double, height:Double)
    {
        self.width = width
        self.height = height
    }
    
    
    init()
    {
        //        self.width = 0
        //        self.height = 0
        // 構造器代理
        self.init(width:0, height:0)
    }
    func show(){
        print("width = \(width) height = \(height)")
    }
}
var r2 = Rect2()
r2.show()
var r3 = Rect2(width: 100, height: 100)
r3.show()

通過閉包或者全局函數/類方法 設置存儲屬性的缺省值



func getTel() ->Int{
    print("getTel")
    return 11111111111
}
class Person4{
    var name : String
    //系統在初始化的時候回隱式執行閉包,將閉包的執行結果賦值給存儲屬性
    var age : Int = {
        print("age 閉包")
        return 30
    }()
    lazy var height:Double = {
        print("lazy 閉包")
        return 180.0
    }()
    
    
    class func getAddress() -> String{
        print("class getAddress")
        return "北京"
    }
    
    func getNickName() -> String
    {
        return "小明"
    }
    
    var tel = getTel()
    var address = Person4.getAddress()
    /*
     不能這樣寫, 因為調用方法時對象還沒有初始化完畢
     self只有當所有的存儲屬性都初始化完畢之后才可以用
     var nickName = self.getNickName
    */
    
    init(name:String)
    {
        print("init")
        self.name = name
    }
}


var p5 = Person4(name: "zx")
// 懶加載是用到時才執行, 而閉包賦值是初始化時就會執行
print(p5.height)
/*
 執行結果:
 age 閉包
 getTel
 class getAddress
 init
 lazy 閉包
 180.0
 */

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容