考虑两个类。首先是 Vehicle
,一个 NSObject
符合的子类 NSCopying
:
class Vehicle : NSObject, NSCopying {
var wheels = 4
func copyWithZone(zone: NSZone) -> AnyObject {
let vehicle = self.dynamicType()
vehicle.wheels = self.wheels
return vehicle
}
}
第二节课, Starship
,继承自 Vehicle
:
class Starship : Vehicle {
var photonTorpedos = 6
var antiGravity = true
override func copyWithZone(zone: NSZone) -> AnyObject {
let starship = super.copyWithZone(zone) as Starship
starship.photonTorpedos = self.photonTorpedos
starship.antiGravity = self.antiGravity
return starship
}
}
此代码无法编译,因为:
使用元类型值构造类型为“Vehicle”的对象必须使用“必需”初始值设定项。
所以我继续添加一个必需的初始化程序:
required override init () {
super.init()
}
现在应用程序编译,和 Starship
对象回应 copy()
正常。
两个问题:
- 为什么构造具有元类型的对象需要a
required
初始化? (看来我写的初始化程序什么也没做。)
- 有没有我写错了,或者 应该 添加到初始化程序?有没有我不考虑的情况?
简答
你不能用 self.dynamicType()
没有标记 init()
如 required
因为没有保证子类的 Vehicle
也将实施 init()
。
探索问题
看看 Swift编程语言:初始化,它提到了如何
默认情况下,子类不会继承其超类初始值设定项
子类的情况 将 继承其超类的初始化者是:
假设您为任何新属性提供默认值
在子类中引入,以下两个规则适用:
规则1
如果您的子类没有定义任何指定的初始值设定项,那么
自动继承其所有超类指定的初始值设定项。
规则2
如果您的子类提供了其所有超类的实现
指定的初始化程序 - 通过按照规则1继承它们,或者通过
提供自定义实现作为其定义的一部分 - 然后它
自动继承所有超类便利初始化程序。
看看这个例子:
class MySuperclass {
let num = 0
// MySuperclass is given `init()` as its default initialiser
// because I gave `num` a default value.
}
class MySubclass : MySuperclass {
let otherNum: Int
init(otherNum: Int) {
self.otherNum = otherNum
}
}
根据以上信息,自此 MySubclass
定义了财产 otherNum
没有初始值,它不会自动继承 init()
从 MySuperclass
。
现在假设我要添加以下方法 MySuperclass
:
func myMethod() {
println(self.dynamicType().num)
}
你会得到你描述的错误,因为没有保证的子类 MySuperclass
将实施 init()
(在这个例子中他们没有)。
因此,要解决此问题,需要进行标记 init()
如 required
,以确保所有子类 MySuperclass
实行 init()
等等 self.dynamicType()
是一件有效的事情。这与问题中的问题相同:斯威夫特知道 Vehicle
器物 init()
但是它不知道任何子类将实现 init()
所以你需要做到 required
。
在您的示例中不适合的替代解决方案是标记 Vehicle
如 final
,意思 Vehicle
不能分类。然后你就可以使用了 self.dynamicType()
;但你可能只是使用 Vehicle()
在这种情况下。
简答
你不能用 self.dynamicType()
没有标记 init()
如 required
因为没有保证子类的 Vehicle
也将实施 init()
。
探索问题
看看 Swift编程语言:初始化,它提到了如何
默认情况下,子类不会继承其超类初始值设定项
子类的情况 将 继承其超类的初始化者是:
假设您为任何新属性提供默认值
在子类中引入,以下两个规则适用:
规则1
如果您的子类没有定义任何指定的初始值设定项,那么
自动继承其所有超类指定的初始值设定项。
规则2
如果您的子类提供了其所有超类的实现
指定的初始化程序 - 通过按照规则1继承它们,或者通过
提供自定义实现作为其定义的一部分 - 然后它
自动继承所有超类便利初始化程序。
看看这个例子:
class MySuperclass {
let num = 0
// MySuperclass is given `init()` as its default initialiser
// because I gave `num` a default value.
}
class MySubclass : MySuperclass {
let otherNum: Int
init(otherNum: Int) {
self.otherNum = otherNum
}
}
根据以上信息,自此 MySubclass
定义了财产 otherNum
没有初始值,它不会自动继承 init()
从 MySuperclass
。
现在假设我要添加以下方法 MySuperclass
:
func myMethod() {
println(self.dynamicType().num)
}
你会得到你描述的错误,因为没有保证的子类 MySuperclass
将实施 init()
(在这个例子中他们没有)。
因此,要解决此问题,需要进行标记 init()
如 required
,以确保所有子类 MySuperclass
实行 init()
等等 self.dynamicType()
是一件有效的事情。这与问题中的问题相同:斯威夫特知道 Vehicle
器物 init()
但是它不知道任何子类将实现 init()
所以你需要做到 required
。
在您的示例中不适合的替代解决方案是标记 Vehicle
如 final
,意思 Vehicle
不能分类。然后你就可以使用了 self.dynamicType()
;但你可能只是使用 Vehicle()
在这种情况下。
你需要一个 required
初始化程序因为Swift中所需的初始化程序的子类实现需要它。
每个Swift文档 所需的硝化剂:
您还必须在每个子类之前编写所需的修饰符
执行一个必需的初始化程序,以表示该
初始化程序要求适用于链中的其他子类。