【问题标题】:Swift: Difference between initializing superclass with a convenience initializer and a designated initializerSwift:使用便利初始化程序和指定初始化程序初始化超类之间的区别
【发布时间】:2018-01-18 09:20:55
【问题描述】:

假设我有一个类 Dog 声明如下:

class Dog {
    let variable1: String
    let variable2: Int

    init(variable1: String, variable2: Int) {
        self.variable1 = variable1
        self.variable2 = variable2
    }
}

ChowChowDog的子类,特意声明为空,如下:

class ChowChow: Dog {}

现在假设我希望向子类ChowChow 添加一个初始化程序。

我的问题是:为子类ChowChow 使用便利初始化程序之间有什么区别(如果有的话):

class ChowChow: Dog {
    convenience init() {
        self.init(variable1: "value1", variable2: 2)
    }
}

和子类ChowChow指定初始化器?:

class ChowChow: Dog {
    init() {
        super.init(variable1: "value1", variable2: 2)
    }
}

使用以下测试,我可以看到两种实现的结果都是相同的:

let chowchow = ChowChow()
print(chowchow.variable1) // Prints "value1"
print(chowchow.variable2) // Prints "2"

提前感谢您的启发!

【问题讨论】:

    标签: swift


    【解决方案1】:

    关于基本 Swift 4.0 规范,指定初始化器和便利初始化器之间的差异与其他任何情况一样。

    此处使用的积分:

    • 便利构造器必须调用其他构造器并最终调用指定构造器
    • 指定的初始化程序必须并且只能调用超类初始化程序(如果有)
    • 默认情况下,子类不会从超类继承指定的初始化程序。假设您为在子类中引入的任何新属性提供默认值,如果您的子类没有定义任何指定的初始值设定项,它会自动继承其所有超类指定的初始值设定项。 (见Automatic Initializer Inheritance

    在你的例子中:

    class ChowChow: Dog {
        convenience init() {
            self.init(variable1: "value1", variable2: 2)
        }
    }
    

    您没有向ChowChow 子类引入任何指定的初始化程序,因此,所有来自超类的指定初始化程序都被继承(即init(variable1:variable2))。由于便利初始化程序最终必须调用指定的初始化程序,因此您从便利初始化程序调用继承的self.init(variable1: "value1", variable2: 2),请注意 self 那里。

    在你的第二个例子中:

    class ChowChow: Dog {
        init() {
            super.init(variable1: "value1", variable2: 2)
        }
    }
    

    您将指定的初始化器init() 引入子类。默认情况下,指定的初始化器不会在子类中继承,除非满足某些条件(如第一个示例)。所以,在这个特定的情况下,子类ChowChow只有一个指定的初始化器init(),没有别的,因为指定的初始化器必须从超类调用指定的初始化器,你调用超类的super.init(variable1: "value1", variable2: 2),注意super。

    详情见:Initializer Inheritance and Overriding

    【讨论】:

    • 您好,感谢您的回复。但是,我仍然不确定这个问题是否得到了彻底的回答:通过便利初始化程序和指定初始化程序初始化超类之间有什么区别(如果有的话)?我可能错了,但您的解释更多的是对我的代码的描述。
    • 这真的取决于你在问什么,否则这个答案有所有需要的信息。许多其他差异是实现细节并且可能会发生变化,因此您无需考虑它们(调查查看来源)。
    • 是的,信息是存在的,在提问之前我也研究过,但是这个问题并没有真正得到回答,因为你的回答看起来更像是对我的代码的描述。不过还是谢谢。感谢您的时间。
    • 那你真的应该详细说明你的问题,具体说明你在问什么。因为从不同的角度和不同的抽象层来看,存在差异而没有差异。我不明白你到底在问哪个部分。就像它们中的任何一个使用哪个调度或类/方法在内存中的表示方式,或者与您相关的任何内容。 IE。您的问题过于笼统,需要规范。
    • 你不认为这正是我想要做的,即。找出区别是什么?无论如何,此时此刻,我认为我已经尽可能详细地发布了我的问题。当我发现任何可靠的东西时会添加它。您对我的代码的描述目前对我并没有真正的帮助,但无论如何感谢您的努力。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多