覆盖Swift中的超类初始化程序

时间:2017-05-25 18:16:34

标签: swift compiler-errors singleton override initializer

我在Swift 3中发现了许多使用Singleton模式的例子。我尝试使用这种方法:

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

当我这样做时,我收到编译错误:

  

覆盖声明需要'覆盖'关键字

当我添加override关键字时,它会编译并且一切似乎都有效。是否需要覆盖因为我是RailsData的子类? RailData是一个抽象类,因为它不是直接实例化的。我也没有把它变成 singleton

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

2 个答案:

答案 0 :(得分:1)

您没有做错任何事情;)override修饰符必需,因为您的RailsData超类使用指定的初始化程序 >完全相同的签名:

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

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

  

当您编写与超类指定初始值设定项匹配的子类初始值设定项时,您实际上提供了对该指定初始值设定项的覆盖。因此,您必须在子类的初始化程序定义之前编写override修饰符。即使您覆盖自动提供的默认初始化程序,也是如此。

     

与重写的属性,方法或下标一样,覆盖修饰符的存在会提示Swift检查超类是否具有要覆盖的匹配的指定初始值设定项,并验证是否已按预期指定了覆盖初始值设定项的参数。

请放心,以后你不会被这个人咬伤;)

激励示例。要查看此初始值设定项覆盖,请尝试以下示例:

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.   
  3. SubClass.init(x:123)
  4.   
  5. SuperClass.init(x:123)
  6.   
  7. SubClass.init(x:123)
  8.   

抽象类。顺便说一句,Swift中的抽象类没有直接的语言支持 - 也不是Objective-C - 但至少Cupertino is thinking about it;)目前,这样的概念仅仅是框架作者等使用的 soft 约定。

答案 1 :(得分:0)

要添加到@Paulo Matteo的全面答案中,很可能是您需要的解决方案:

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