在Swift中使用子类实现NSCopying
考虑两个类。第一个是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”初始化程序。
因此,我继续添加所需的初始化程序:
required override init () { super.init()
}
现在,应用程序可以编译,并且Starship
对象可以copy()
正确响应。
两个问题:
- 为什么构造具有元类型的对象需要
required
初始化程序?(看来我编写的初始化程序没有任何作用。) - 我写错了什么,还是 应该 添加到初始化程序?我有没有考虑的情况?
回答:
回答:
您不能在self.dynamicType()
没有标记的情况下使用init()
,required
因为不会保证Vehicle
will的子类也将实现init()
。
回答:
看一下《 The Swift Programming
Language:Initialization》
,其中提到了
子类默认情况下不继承其超类初始化程序
子类 继承其超类的初始化程序的情况是:
假设为子类中引入的任何新属性提供默认值,则适用以下两个规则:
如果您的子类没有定义任何指定的初始化器,它将自动继承其所有超类的指定初始化器。
如果您的子类提供了其所有超类指定的初始化程序的实现(通过按照规则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
Implement的所有子类init()
,因此调用self.dynamicType()
是正确的做法。问题与您的问题相同:Swift知道Vehicle
实现init()
,但是它不知道任何子类将实现init()
,因此您需要使其实现required
。
在您的示例中不适合的另一种解决方案是将标记Vehicle
为final
,表示Vehicle
不能被子类化。这样就可以使用self.dynamicType()
;
但您最好还是Vehicle()
在这种情况下使用。
以上是 在Swift中使用子类实现NSCopying 的全部内容, 来源链接: utcz.com/qa/411302.html