问题
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:)
关键字会产生编译错误。我是否错误地理解了这些初始化概念?
答案 0 :(得分:13)
The reason override
is unneeded:
相反,如果编写一个与超类便利初始化程序匹配的子类初始值设定项,则根据上面在Initializer Chaining中描述的规则,您的子类永远不能直接调用该超类便捷初始化程序。因此,您的子类(严格来说)不提供超类初始化程序的覆盖。因此,在提供超类便捷初始化程序的匹配实现时,不要编写
override
修饰符。
但是正如所写的那样,它似乎应该可行 - 据我所知,这是一个编译器错误。如果将array
参数的名称更改为ClassB的初始化程序,例如array2
,然后按预期工作。你应该file a Radar!