Swift学习之构造过程

构造过程

类和结构体的存储属性必须在实例创建时,设定合适的初始值,可以提供默认值,也可以在构造器中提供初始值

1.构造参数

如果构造器的参数使用了外部参数名,必须使用,也可以用 _ 代替,不适用外部参数名

struct Celsius {
    var temperatureInCelsius:Double //这里也可以提供初始值,也可以不提供,因为下面的构造器中在实力创建时会提供初始值

    init(oneTemperature one :Double){
        temperatureInCelsius = one + 10
    }
    init (twoTemperature two :Double){
        temperatureInCelsius = two - 10
    }
}

let oneCelsius = Celsius(oneTemperature: 0)
let twoCelsius = Celsius(twoTemperature: 20)
print("oneCelsius is :\(oneCelsius.temperatureInCelsius),towCelsius is \(twoCelsius.temperatureInCelsius)")  //oneCelsius is :10.0,towCelsius is 10.0

class Question {
    var text:String
    var response:String?
    let id :String
    init(text:String){
        self.text = text
        id = text + "001" //构造过程中对常量的改变
    }
    func ask(){
        print(self.text)
    }
}
var question = Question(text: "Can i ask a question")
question.ask() //Can i ask a question
print(question.response) //nil,因为是可选的,如果不提供默认值,会自动的赋值为nil
print(question.id) // Can i ask a question001
2.默认构造器

类和结构体如果都没用提供构造器,则类默认的提供一个init(){}构造器,结构体提供一个逐一成员构造器

3.值类型的构造器代理
struct Point {
    var x :Double = 0.0 ,y:Double = 0.0
}
struct Size {
    var width :Double = 0.0 ,height:Double = 0.0
}
struct Rect {
    var point = Point()
    var size = Size()
    init(){}
    init(origin:Point,size:Size){
        self.point = origin
        self.size = size
    }
    init(center:Point,size:Size){
        let originX = center.x - (size.width / 2)
        let originY = center.y - (size.height / 2)

        //self.point = center 在这里还没有调用指定构造器,不能直接赋值

        //self.point 出现 error: use of 'self' in delegating initializer before self.init is called

        //指向了init(origin:size:)构造器
        self.init(origin:Point(x: originX, y: originY),size: size)

        //self.point = center 在这里就不会发生错误
    }
}
4.类的继承和构造过程
 指定构造器:跟简单的构造器一样 init(parameters){} 总是向上代理
 便利构造器:convince init(parameters){}  总是横向代理

 二个阶段
 (1)实例没有创建成功,内存还没有初始化完,会沿着构造器链往上执行,直到所有的属性给初始化完毕,实例创建成功,内存初始化完
 (2)向下执行额外的属性赋值等操作

 三条原则
 (1)指定构造器必须继承父类的指定构造器
 (2)便利构造器必须调用同一类的其他构造器
 (3)便利构造器必须最终导致一个指定构造器被调用

 四个检查
 (1)指定构造必须先将引入的属性给初始化完毕才能将构造任务向上代理给父类的指定构造器
 (2)指定构造器必须先向上代理给父类的指定构造器之后才能修改继承过来的属性
 (3)便利构造器必须先横向代理给同一类中得指定构造器,才能任意的给属性赋值
 (4)在第一阶段完成之前,不能调用任何实例方法,不能读取任何实例的属性,也不能引用self作为实例
5.可失败构造器
struct Animal {
    let species :String
    init?(species:String){
        if species.isEmpty{return nil}
        self.species = species
    }
}

class Product {
    let name:String!
    init?(name:String){
        //if name.isEmpty{return nil} 所有的存储属性必须在return之前
        self.name = name
        if name.isEmpty{return nil}
    }
}

class CarItem: Product {
    var quantity:Int!
    var price:Int={
        return 10
    }() //可以通过闭包给属性赋值,但是在闭包最后必须加()代表立即执行

    init?(name: String,quantity:Int) {
        //if quantity < 1 {return nil} 所有的存储属性必须在return之前
        self.quantity = quantity
        //if quantity < 1 {return nil} super.init must be called before returning nil
        super.init(name: name)

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值