在Swift中初始化子类时调用父构造函数

luc*_*cio 9 swift

我有一些继承自基类的类.通常使用c ++类,我习惯在子代中重写构造函数,然后调用父代.

在初始化子类时如何在Swift中调用父构造函数而不重写它?

internal class A {
    init(aBool: Bool? = false) {
        ...
    }
}

class B: A {
    init(aString: String) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

以这两个类为例,我想使用A构造函数初始化B:

let obj = A(true)
Run Code Online (Sandbox Code Playgroud)

Aar*_*sen 12

Apple的规则规定:

默认情况下,[S] ubclasses不继承其超类初始值设定项.但是,如果满足某些条件,则会自动继承超类初始值设定项.实际上,这意味着您不需要在许多常见场景中编写初始化程序覆盖,并且可以在安全的情况下以最小的努力继承您的超类初始化程序.

假设您为在子类中引入的任何新属性提供默认值,则适用以下两个规则:

规则1:如果您的子类没有定义任何指定的初始值设定项,它会自动继承其所有超类指定的初始值设定项.

规则2:如果您的子类提供了所有超类指定初始值设定项的实现 - 通过按照规则1继承它们,或者通过提供自定义实现作为其定义的一部分 - 那么它会自动继承所有超类便捷初始值设定项.

即使您的子类添加了更多便利初始值设定项,这些规则也适用.

这意味着什么?如果你使你的子类B的初始化器成为一个便利初始化器,那么B应该继承所有A的指定初始化器.

class B: A {
    convenience init(aString: String) { ... }
}
Run Code Online (Sandbox Code Playgroud)


Gri*_*mxn 6

如果您将Binit设置为init convenience init,它将不会掩盖原始图像,init并且您可以执行此操作...

class A {
    var b: Bool? = nil
    init(aBool: Bool? = false) {
        self.b = aBool
    }
}

class B: A {
    var s: String? = nil
    convenience init(aString: String) {
        self.init(aBool: false)
        self.s = aString
    }
}

let obj1 = A(aBool: true) // obj1 is now an A, obviously.
let obj2 = B(aBool: true) // obj2 is now a B
Run Code Online (Sandbox Code Playgroud)

不过,您必须谨慎设置默认值或设置所有属性。

另外,您也可以override将原件init放入B,然后只需致电super.init