构造方法总结一

2017-08-30  本文已影响10人  来金德瑞

作用:对实例对象的内容进行初始化
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
 */

上一篇下一篇

猜你喜欢

热点阅读