假设我有一个类 Dog
声明如下:
class Dog {
let variable1: String
let variable2: Int
init(variable1: String, variable2: Int) {
self.variable1 = variable1
self.variable2 = variable2
}
}
而ChowChow
是Dog
的子类,故意声明为空如下:
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 4.0- 规范,指定初始化器和便利初始化器之间的区别与任何其他情况相同。
此处使用的点:
- 便利构造器必须调用其他构造器并最终调用指定构造器
- 指定的初始化器必须并且只能调用父类(super class)初始化器(如果有的话)
- 默认情况下,子类不从父类(super class)继承指定的初始值设定项。假设您为在子类中引入的任何新属性提供默认值,如果您的子类没有定义任何指定的初始化器,它会自动继承其父类(super class)的所有指定初始化器。 (参见 Automatic Initializer Inheritance)
在你的例子中:
class ChowChow: Dog {
convenience init() {
self.init(variable1: "value1", variable2: 2)
}
}
您没有为 ChowChow
子类引入任何指定的初始值设定项,因此,所有来自父类(super class)的指定初始值设定项都是继承的(即 init(variable1:variable2)
)。由于便利初始化器最终必须调用指定的初始化器,因此您从便利初始化器调用继承的 self.init(variable1: "value1", variable2: 2)
,注意 self 。
在你的第二个例子中:
class ChowChow: Dog {
init() {
super.init(variable1: "value1", variable2: 2)
}
}
您将指定的初始化器 init()
引入子类。默认情况下,指定的初始化器不会在子类中继承,除非满足某些条件(如第一个示例)。因此,在这种特定情况下,子类 ChowChow
只有一个指定的初始化器 init()
,因为指定的初始化器必须从父类(super class)调用指定的初始化器,所以您调用父类(super class)的 super.init(variable1: "value1", variable2: 2)
,这里注意super。
关于Swift:使用便利初始化器和指定初始化器初始化父类(super class)之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48317664/