方便初始覆盖 [英] Convenience Init Override

查看:147
本文介绍了方便初始覆盖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题

覆盖子类的便利初始值设定项并生成编译错误。

Override a convenience initializer of a subclass and it produces a compile error.

详细信息

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

I am having issues understanding why Swift (v4.1) is not letting me override my convenience initializer. Reading the documentation I found that these two rules apply to my question:


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

Rule 1 If your subclass doesn’t define any designated initializers, it automatically inherits all of its superclass designated initializers.

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

Rule 2 If your subclass provides an implementation of all of its superclass designated initializers—either by inheriting them as per rule 1, or by providing a custom implementation as part of its definition—then it automatically inherits all of the superclass convenience initializers.

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

In the code below I fall under the first rule and all my convenience initializers are inherited into ClassB. Furthermore, since I inherited all the designated initializers as per rule one, I also get all my convenience initializers inherited.

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 init(array:)的实现略有不同,我想覆盖那个便利初始化程序。使用覆盖关键字会产生编译错误。我是否错误地理解了这些初始化概念?

But here is what I don't understand: ClassB has a slightly different implementation of init(array:) and I would like to override that convenience initializer. Using the override keyword produces a compile error. Am I understanding these initialization concepts wrongly?

推荐答案

原因覆盖不需要


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

Conversely, if you write a subclass initializer that matches a superclass convenience initializer, that superclass convenience initializer can never be called directly by your subclass, as per the rules described above in Initializer Chaining. Therefore, your subclass is not (strictly speaking) providing an override of the superclass initializer. As a result, you do not write the override modifier when providing a matching implementation of a superclass convenience initializer.

但是如上所述,它似乎应该可行 - 据我所知,这是一个编译器错误。如果将ClassB的初始值设定项的数组参数更改为例如 array2 ,然后按预期工作。您应该提交雷达

But as written, it seems it should work — as far as I can tell this is a compiler bug. If you change the name of the array argument to ClassB's initializer to e.g. array2, then it works as expected. You should file a Radar!

这篇关于方便初始覆盖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆