一个快速子类*总是*必须调用Super.init()吗?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (11)

如果我有一个快速子类,那就是:

  1. 不需要访问self
  2. 不需要访问self

super.init()在子类中init()方法?

提问于
用户回答回答于

假设您有以下类。

class a {
    let name: String

    init() {
        name = "james"
    }
}

class b: a {
    let title: String

    override init() {
        title = "supervisor"
    }
}

如果您实例化一个变量

let myVar = b()

然后,

  • override init()b会被召唤
  • 然后init()a会被召唤

即使你没有明确的打电话给super.init()...

这一点已经被ChrisLaettner在快速用户的电子邮件列表上证实了。当超类有一个带有零参数的指定初始化器时,它就会启动。这就是为什么在从NSObject派生时不必调用Super.init()的原因。

用户回答回答于

从那里得知:

指定的初始化器必须从它们的直接超类调用指定的初始化器。

另外,关于自动初始化继承:

假设为子类中引入的任何新属性提供默认值,则适用以下两条规则:规则1如果子类没有定义任何指定的初始化器,则它会自动继承其所有指定的超类初始化器。规则2如果子类提供了它指定的所有超类初始化器的实现--或者按照规则1继承它们,或者提供自定义实现作为其定义的一部分--那么它将自动继承所有超类方便初始化器。 即使子类添加了更多方便的初始化器,这些规则也适用。

因此,你的问题的答案如下:

你的子类调用超类的指定初始化程序。如果不编写初始化程序,编译器也不抱怨,那么它就使用了自动初始化继承。如果确实编写了一个初始化程序,但它没有显式地调用相关的上游(或侧流)初始化程序,那么它将在初始化程序的末尾自动为您完成。

此外,链式初始化器的工作方式是一个两阶段的过程.。在第一阶段,它从子类开始到超类,将默认值分配给任何参数。在第二阶段,流程将向后运行,从超类开始,以子类结束,在子类中,参数的定制将被完成并重写。

这意味着你必须绝对地在每一个init()设置变量,然后您就可以调用(或不调用)super.init()运行自定义代码。因此,正如在上面所问的,如果希望超级程序的init在开始时运行,请考虑“开始”就在创建变量之后:

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()

这将打印A,然后b。

扫码关注云+社区