Swift类初始化

默认初始化方法

  1. 类没有成员初始化方法;
  2. 类拥有空初始化方法条件:类的所有属性都有默认值 && 没有自定义初始化方法。

自定义初始化方法

  1. 指定初始化方法

    • 指定初始化方法用关键字init表示;
    • 如果有父类,则子类的指定初始化方法必须调用父类的指定初始化方法。
    • 子类在初始化方法的最后调用父类的初始化方法。因为子类的初始化方法负责为自己引入的所有属性赋值,子类属性赋值后,再调用父类的初始化方法,以便父类初始化自己的属性。
  2. 便捷初始化方法

    • convenience标记init方法
    • 不需要确保类的所有属性都有值
    • 需要调用其他便捷初始化方法或指定初始化方法,最终便捷初始化方法必须调用到指定初始化方法。
  3. 可失败的初始化方法

    • 返回可空实例,会增加工程复杂度,容易出错,只在必要情况下使用

    • 方法用init?标记表示这个初始化方法可能失败

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      struct Man{
      init?(name: String, age: Int){
      guard age > 0 else{
      return nil
      }
      self.name = name
      self.age = age
      }
      }

      var David = Man(name:"David", age:10)
      let nameStr = David?.name
      print(nameStr)
    • init!标记返回隐式展开可空类型,则不需要写可空类型展开的语法,Swift利用这些语法使可空类型更安全。但安全性大大下降。

初始化方法自动继承

  1. 一般情况下,子类不继承父类的初始化方法;

  2. 子类自动继承父类初始化方法的场景:

    • 子类新增属性有默认值 && 子类没有定义任何指定初始化方法——>子类继承父类的指定初始化方法;
    • 子类新增属性有默认值 && 子类实现了父类的所有指定初始化方法(显式实现或隐式继承)——>子类继承父类的所有便捷初始化。
  3. 必需初始化方法

    父类可以要求其子类提供特定的初始化方法:

    • 父类和子类都用required标记init方法,而不是用override关键字来标记;

    • 子类需要调用父类初始化方法

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      //父类
      required init(town: Town?,monsterName: String){
      self.town = town
      name = monsterName
      }

      //子类
      required init(town: Town?,monsterName: String){
      walksWithLimp = false// 子类的新增属性
      isFallingApart = false
      super.init(town:town,monsterName:monsterName)
      }