在 Swift 中重写超类初始值设定项

Overriding superclass initializer in Swift

我在 Swift 中找到了许多使用单例模式的示例。 3. 我正在尝试使用此方法:

class Records: RailsData {
    static let shared = Records()
    private init() {} 
    ...
}

当我这样做时,出现编译器错误:

Overriding declaration requires an 'override' keyword

当我添加 override 关键字时,它编译并且似乎一切正常。是否需要覆盖,因为我是 subclassing RailsDataRailData 是一个抽象 class 因为它没有直接实例化。我也没有把它变成单例.

我试图通过使用 override 修饰符来确保我以后不会被咬...

你没有做错任何事 ;) override 修饰符是 必需的 因为你的 RailsData 超类声明了一个 指定的初始化器 完全 相同的签名:

class RailsData {
    init() {...}
    ...
}

因此,override 修改在您的子类中是必需的。同样的事情也适用于继承的方法。来自 The Swift Programming Language book:

When you write a subclass initializer that matches a superclass designated initializer, you are effectively providing an override of that designated initializer. Therefore, you must write the override modifier before the subclass’s initializer definition. This is true even if you are overriding an automatically provided default initializer.

As with an overridden property, method or subscript, the presence of the override modifier prompts Swift to check that the superclass has a matching designated initializer to be overridden, and validates that the parameters for your overriding initializer have been specified as intended.

放心,以后不会被这个咬到;)


激励示例。要查看此 初始化程序覆盖 的实际效果,请尝试以下示例:

class SuperClass {
    init(x: Int) {
        print("3. SuperClass.init(x: \(x))")
    }
    convenience init() {
        print("1. SuperClass.init()")
        self.init(x: 123) // Will be overridden by subclass.
    }
}

class SubClass: SuperClass {
    override init(x: Int) {
        print("2. SubClass.init(x: \(x))")
        super.init(x: x)
        print("4. SubClass.init(x: \(x))")
    }
}

// Calls inherited convenience initializer.
let sub = SubClass() 

输出:

  1. SuperClass.init()
  2. SubClass.init(x: 123)
  3. SuperClass.init(x: 123)
  4. SubClass.init(x: 123)

摘要类。顺便说一句,abstract 类Swift — nor in Objective-C — but at least Cupertino is thinking about it 中没有直接的语言支持 ;) 目前,这样的概念只是一个 soft 框架作者等使用的约定

要添加到@Paulo Matteo 的综合答案,这很可能是您需要的修复:

override private init() {
    super.init()
}