Swift 构造过程 2

16 篇文章 0 订阅

Swift中类的构造过程分为两个阶段
1. 每个存储属性在它们被引入的类中会被指定一个初始值当所有的存储属性都有一个初始值后第二阶段开始。
2. 在新实例使用之前,允许每个类进一步定制它们的存储属性。

类的代理规则

  1. 子类中的指定构造器必须调用父类的指定构造器(如果本身是父类可以忽略这条)
  2. 一个类的便利构造器必须调用这个类的其他构造器(横向代理)
  3. 一个类的便利构造器必须最终调用这个类的指定构造器(向上代理)

类的指定构造器

父类的指定构造器

class Book {
    var boonName:String
    var bookPrice:Double
    var sendFriend:String {
        get {
            return boonName
        }
    }
    //指定构造器
    init(name:String,price:Double) {
        boonName = name;
        bookPrice = price
    }
}
  • 指定构造器的语法跟值类型构造器的语法相同

我们可以直接使用指定构造器来初始化一个实例如:var book3 = Book(name: "Like", price: 99)

子类的指定构造器

class MyBook:Book {
    var publicationDate:String

    //指定构造器
    init(name:String,price:Double,date:String) {
        publicationDate = date
        //规则1,指定构造器必须调用父类中的指定构造器
        super.init(name: name, price: price)
        bookPrice = 100
    }
}

MyBook这个类继承自Book,对于子类的指定构造器有如下需要注意的:

  • 在子类的指定构造器中必须先给新引入的属性赋值
  • 子类中的指定构造器必须代理父类中指定构造器super.init(...)
  • 子类中指定构造器必须在代理父类中的指定构造器后再设置继承来的属性值,在之前设置继承的属性值会在调用父类的指定构造器过程中被覆盖的。

我们可以用MyBook的指定构造器初始化:var myBook5 = MyBook(name: "Five", price: 9.9, date: "1992")

类的便利构造器

对于Book这个类我们新增两个便利构造器

    convenience init(freeBookName:String) {
        self.init(name: freeBookName, price: 0)
    }

    convenience init() {
        self.init(freeBookName:"Love China")
    }

对于MyBook这个类新增两个便利构造器

    convenience init(myBookName:String,price:Double) {
        self.init(name: myBookName, price: price, date: "today")
        if bookPrice > 50 {
            self.bookPrice = 50
        }
    }
    convenience override init(name: String, price: Double) {
        self.init(myBookName: name, price: price)
        self.publicationDate = "2017"
    }

对于便利构造器我们有一下几点:

  • 便利构造器必须先代理类中的其他构造器

  • 便利构造器必须最终代理到指定构造器

  • 在便利构造器必须先代理其他构造器再修改属性值

  • 在构造器的第一阶段完成前是无法使用self,无法调用实例方法。

  • 在便利构造器中我们必须在代理其他构造器后才可以是有self,实例方法

    我们可以通过便利构造器来初始化一个实例:var myBook3 = MyBook(name: "World", price: 22),其用法与指定构造器一样

类的可失败构造器

对于Book这个类新增一个可失败构造器

    init?(highPrice:Double) {
        if  highPrice < 100 { return  nil }
        self.boonName = "Price"
        self.bookPrice = highPrice
    }
  • 可失败构造器的语法跟指定构造器的区别是在init后多了一个?
  • 可失败构造器是指在构造过程当不满足某些条件时返回nil值,在使用可失败构造器初始化实例时返回的是一个可选
  • 如果在子类的非可失败构造器中向上代理到父类的可失败构造器,那么需要对父类的可失败构造器的代理结果强制解包

我们可以这样来使用一个可失败构造器:

if var book4 = Book(highPrice: 55) {
    book4.bookPrice
    book4.boonName
}else {
    var book5 = Book(highPrice: 120)
}

类的必要构造器

对于Book这个类,新增一个必要构造器

   required init (lowPrice:Double) {
        boonName = "Run"
        bookPrice = lowPrice
    }
  • 必要构造器需要在构造器前面添加关键字 required

  • 必要构造器要求子类也要重写这个构造器,并且子类重写的构造器也要添加关键字required

类的继承与重写

类的继承

Swift里面的类不会像OC里面子类会自动继承父类的构造方法,必须要满足一定条件子类才会继承父类的构造方法

  • 当满足前提:子类中新引入的属性都有默认值时有下面的规则适用:

    • 如果子类没有提供自己的指定构造器那么它将自动继承父类的指定构造器

    • 如果子类有提供所有父类的指定构造器的实现(可以是通过满足前面条件继承来的也可以是在子类中重写的),那么子类将默认继承父类的便利构造器

类的重写

子类可以对父类的构造器进行重写,对于重写有如下的一些总结:

  • 如果父类有必要构造器,子类必须重写父类的必要构造器
  • 子类可以将父类的指定构造器重写成子类的指定构造器,在构造器前加关键字override
  • 子类可以将父类的指定构造器重写成为子类的便利构造器,在构造器前加关键字convenience override
  • 子类严格意义来说是无法重写父类的便利构造的,但是可以在子类中指定一个跟父类的便利构造器一下的构造器实现,这个构造器可以是子类的便利构造器也可以是子类的指定构造器,无论是哪种都不要有override关键字
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值