我有以下的例子在斯威夫特遊樂場,企圖實現雨燕拷貝構造函數:如何在Swift子類中實現複製構造函數?
class Shape : NSObject {
var color : String
override init() {
color = "Red"
}
init(copyFrom: Shape) {
color = copyFrom.color
}
}
class Square : Shape {
var length : Double
override init() {
super.init()
length = 10.0
}
init(copyFrom: Square) { /* Compilation error here! */
super.init(copyFrom: copyFrom)
length = copyFrom.length
}
}
let s : Square = Square() // {{color "Red"} length 10.0}
let copy = Square(copyFrom: s) // {{color "Red"} length 10.0}
s.color = "Blue" // {{color "Blue"} length 10.0}
s // {{color "Blue"} length 10.0}
copy // {{color "Red"} length 10.0}
的問題是,這實際上並不在其目前的形式編譯。論Square
子類中的方法init(copyFrom: Square)
,報告這個錯誤:
Overriding method with selector 'initWithCopyFrom:' has incompatible type '(Square) -> Square'
這個問題將使意義,如果它不是一個構造,就好像它是一個普通func
,你可以可能會傳入超類中預期的類型,但在子類中被覆蓋的類型更具限制性:
let mySquare : Shape = Square() // Note the var is a SHAPE
mySquare.someShapeMethod("Test") // If Square overrides someShapeMethod() to expect Int, compiler errors out to protect us here.
但是,構造函數構造函數使我相信我應該能夠覆蓋它並提供不同的方法簽名,因爲在編譯時絕對知道對象的類型是什麼。
如果我將Shape
更改爲不再延伸NSObject
,則此問題將消失。但是,由於包含現有的Objective-C代碼,它需要擴展NSObject
。
我如何更新我的拷貝構造函數允許Shape
知道它是從一個Shape
複製,並允許Square
知道它是從一個Square
複製?
感謝羅布 - 可靠的答案。 – 2014-09-12 13:32:41
你也可能會發現這個討論對於在純Swift中製作副本很有用:http://stackoverflow.com/questions/25645090/protocol-func-returning-self – 2014-09-12 13:41:17
對於Swift 2/Xcode 7,它會是'let theCopy = self。 dynamicType.init()',當然'as!'而不是'as'(僅僅提到,因爲相關的問題出現在這裏:http://stackoverflow.com/questions/31885231/using-object-initializers-in-迅速更換的-allocwithzone)。 – 2015-08-07 19:53:56