Inheritance 便利初始化覆盖

Inheritance 便利初始化覆盖,inheritance,swift,init,Inheritance,Swift,Init,问题 重写子类的方便初始值设定项,它会产生编译错误 细节 我很难理解为什么Swift(v4.1)不允许我覆盖我的便利初始值设定项。阅读文档后,我发现这两条规则适用于我的问题: 规则1 如果您的子类没有定义任何指定的初始值设定项,它将自动继承其所有超类指定的初始值设定项 规则2 如果您的子类通过按照规则1继承其所有超类指定的初始值设定项,或者通过提供自定义实现作为其定义的一部分,来提供其所有超类指定初始值设定项的实现,那么它将自动继承所有超类便利初始值设定项 在下面的代码中,我属于第一条规则,我所

问题

重写
子类的方便初始值设定项,它会产生编译错误

细节

我很难理解为什么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])
A类{
//此数组将是私有的,并且在ClassB中不可见
变量数组:[T]?
init(){}
便利初始化(数组:[T]){
self.init()
self.array=array
}
}
B类:A类{
var另一个数组:[T]?
//我觉得我应该包括“覆盖”关键字
//但当在“便利初始化”之前添加“覆盖”时,我得到了一个编译器错误。
便利初始化(数组:[T]){
self.init()
self.anotherArray=array
}
}
//很好
让instanceA=ClassA(数组:[1,2])
//添加覆盖时出现编译错误:
//错误:初始值设定项未从其超类重写指定的初始值设定项
//注意:尝试在此处重写便利初始值设定项
//便利初始化(数组:[T]){
//                 ^
让instanceB=ClassB(数组:[1,2])
但我不明白的是:
ClassB
init(array:)
有一个稍微不同的实现,我想覆盖这个方便的初始值设定项。使用
override
关键字会产生编译错误。我对这些初始化概念理解错误吗?

:

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


但正如所写的,它似乎应该可以工作-据我所知,这是一个编译器错误。如果您将
数组
参数的名称更改为ClassB的初始值设定项,例如
数组2
,那么它就可以正常工作。您应该

如果要重写的初始值设定项是一个方便的初始值设定项,则重写必须从它自己的子类调用另一个指定的初始值设定项因此,即使我不需要,我也需要创建一个新的指定初始化器?我通过创建一个内部函数解决了我的问题,该函数与方便初始化器所做的逻辑相同。通过这种方式分离代码,我可以正确地覆盖它。这本书是这么说的,但看起来并不正确,因为
init
是一个指定的
ClassB
initializer。这很容易成为一个bug。谢谢@jtbandes,我一定错过了那一部分文档。我会将您的答案设置为可接受的答案。