深入解析Swift编程中的构造方法

2020-01-08 23:07:00王旭

1.子类Designated构造方法中必须调用父类的Designated构造方法。

2.Convenience构造方法中必须调用当前类的构造方法。

3.Convenience构造方法归根结底要调用到Designated构造方法。

官方文档的一张图可以清晰的描述上述关系:

Swift,构造方法,init

四、构造方法的继承关系

关于子类继承父类的构造方法有这样几个特性:

1.如果子类没有复写任何父类的构造方法,则默认子类将继承所有父类的构造方法,包括Designated构造方法与Convenience构造方法。

2.如果子类复写了父类某一构造方法,则子类默认不在继承所有父类的构造方法,对于Designated类型的构造方法,子类复写了哪些,哪些才能够被使用,对于Convenienve类型的构造方法,子类复写的其调用的Designated构造方法后会被自动继承。

3.如果父类中的构造方法是required修饰的,则子类必须进行继承或复写。

曾经有朋友和我抱怨,Objective-C中的继承是一种十分不人性,它强制子类继承所有父类的方法与属性无论子类是否需要,分析上面的一些规则可以发现,Swift与Objective-C相比,在构造方法方面语法会更加严格,这样做在编程上更加安全。在Objective-C中,子类将被强制继承所有父类的初始化方法,这样开发者在使用时常常会出现疑惑,有时一个子类往往有特定的初始化方法,仅仅通过父类的初始化方法不能够正确的完成初始化,在编程时,往往需要特殊注释来提示开发者。Swift设定的这些构造方法原则可以将无关的父类构造方法剔除在外,在编程时更加严格安全,减少疑惑与不可控因素。

五、构造方法的实现原则

无论Designated类型的构造方法还是Convenience类型的构造方法,只要其有父类,最终都要实现父类的Designated构造方法。Swift语言要求,在构造方法中要完成所有成员常量或者变量的构造或赋值(optional值除外)。在对成员常量或变量进行构造赋值时,要在调用父类的初始化方法之前,这里还有一点需要注意,父类的成员属性也会被子类继承,如果要在子类复写的父类方法中对继承来的父类成员属性进行重新构造或赋值,则必须在调用父类构造方法之后,例如创建ClassTwo类继承于ClassOne,复写方法如下:


class ClassTwo: ClassOne {
  //子类自己的属性
  let tipTwo:Int
  override init() {
    //调用父类构造方法前进行自己属性的构造
    tipTwo = 1
    //调用父类构造方法
    super.init()
    //对从父类继承来的属性进行重构造
    tip = 1000;
  }
  
  required init(three: Float) {
    fatalError("init(three:) has not been implemented")
  }
  

}