Does a swift subclass *always* have to call super.init()

前端 未结 4 965
暖寄归人
暖寄归人 2021-01-30 21:46

If I have a swift subclass that:

  1. doesn\'t need to access self
  2. doesn\'t need to access any properties on self

Do

4条回答
  •  一整个雨季
    2021-01-30 22:31

    From the docs:

    Designated initializers must call a designated initializer from their immediate superclass.

    Also, regarding automatic initializer inheritance:

    Assuming that you provide default values for any new properties you introduce in a subclass, the following two rules apply:

    Rule 1 If your subclass doesn’t define any designated initializers, it automatically inherits all of its superclass designated initializers.

    Rule 2 If your subclass provides an implementation of all of its superclass designated initializers—either by inheriting them as per rule 1, or by providing a custom implementation as part of its definition—then it automatically inherits all of the superclass convenience initializers.

    These rules apply even if your subclass adds further convenience initializers.

    So the answer to your question is as follows:

    Your subclass will always call a designated initializer of your superclass. If you don't write an initializer and the compiler doesn't complain, then it has used automatic initializer inheritance. And if you do write an initializer but it doesn't explicitly call a relevant upstream (or sidestream) initializer, it will be done for you automatically at the end of your initializer.

    Furthermore, the way chained initializers work is in a 2-phase process. In the first phase, it starts from the subclasses towards superclasses, assigning default values to any parameters. In the second phase, the process is run backwards, starting with superclasses and ending with your subclass, where the customization of parameters is done and overridden.

    This means that you must absolutely first in each init() set your variables, and then you're free to call (or not) the super.init() and run custom code. So as you asked above, if you want the super's init to run at the beginning, consider the 'beginning' to be just after your creating your variables:

    class a {
        var name: String
    
        init() {
            name = "james"
            println("a")
        }
    }
    
    class b: a {
        let title: String
    
        override init() {
            title = "supervisor"
            super.init()
            self.name = "john"
            println("b")
        }
    }
    
    let x = b()
    

    This will print a, then b.

提交回复
热议问题