在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()正确响应。

两个问题:

  1. 为什么构造具有元类型的对象需要required初始化程序?(看来我编写的初始化程序没有任何作用。)
  2. 我写错了什么,还是 应该 添加到初始化程序?我有没有考虑的情况?

回答:

回答:

您不能在self.dynamicType()没有标记的情况下使用init()required因为不会保证Vehiclewill的子类也将实现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,以确保MySuperclassImplement的所有子类init(),因此调用self.dynamicType()是正确的做法。问题与您的问题相同:Swift知道Vehicle实现init(),但是它不知道任何子类将实现init(),因此您需要使其实现required

在您的示例中不适合的另一种解决方案是将标记Vehiclefinal,表示Vehicle不能被子类化。这样就可以使用self.dynamicType();

但您最好还是Vehicle()在这种情况下使用。

以上是 在Swift中使用子类实现NSCopying 的全部内容, 来源链接: utcz.com/qa/411302.html

回到顶部