方便初始覆盖

时间:2014-08-15 06:59:18

标签: inheritance swift init

问题

Override子类的便利初始化器,它会产生编译错误。

详细

我有理解为什么Swift(v4.1)不允许我覆盖我的便利初始化程序。阅读文档我发现这两条规则适用于我的问题:

  

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

     

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

在下面的代码中,我属于第一条规则,我的所有便利初始化程序都被继承到ClassB。此外,由于我按照规则1继承了所有指定的初始化程序,因此我也继承了所有便利初始化程序。

class ClassA<T> {

    // This array would be private and not visible from ClassB
    var array: [T]?

    init() { }

    convenience init(array: [T]) {
        self.init()

        self.array = array
    }
}

class ClassB<T>: ClassA<T> {

    var anotherArray: [T]?

    // I feel like I should include the "override" keyword
    // but I get a compiler error when "override" is added before "convenience init".
    convenience init(array: [T]) {
        self.init()

        self.anotherArray = array
    }
}

// Works fine
let instanceA = ClassA(array: [1, 2])
// Compile error when override is added:
// error: Initializer does not override a designated initializer from its superclass
// note: attempt to override convenience initializer here
//     convenience init(array: [T]) {
//                 ^
let instanceB = ClassB(array: [1, 2])

但这是我不明白的地方:ClassB的{​​{1}}实现略有不同,我想覆盖那个便利初始化程序。使用init(array:)关键字会产生编译错误。我是否错误地理解了这些初始化概念?

1 个答案:

答案 0 :(得分:13)

The reason override is unneeded

  

相反,如果编写一个与超类便利初始化程序匹配的子类初始值设定项,则根据上面在Initializer Chaining中描述的规则,您的子类永远不能直接调用该超类便捷初始化程序。因此,您的子类(严格来说)不提供超类初始化程序的覆盖。因此,在提供超类便捷初始化程序的匹配实现时,不要编写override修饰符。

但是正如所写的那样,它似乎应该可行 - 据我所知,这是一个编译器错误。如果将array参数的名称更改为ClassB的初始化程序,例如array2,然后按预期工作。你应该file a Radar