Tôi có ví dụ sau đây trong một sân chơi Swift, trong một nỗ lực để thực hiện một constructor sao chép trong Swift:Làm cách nào để triển khai hàm tạo bản sao trong lớp con 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}
Vấn đề là điều này không thực sự biên dịch trong hình thức hiện tại của nó. Trên init(copyFrom: Square)
phương pháp trong Square
lớp con, lỗi này được báo cáo:
Overriding method with selector 'initWithCopyFrom:' has incompatible type '(Square) -> Square'
Vấn đề này sẽ có ý nghĩa nếu nó không phải là một constructor, như thể nó là một thường xuyên func
, bạn có thể có khả năng vượt qua trong một loại được mong đợi trong siêu lớp, nhưng điều đó đã bị ghi đè trong lớp con sẽ hạn chế hơn:
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.
Nhưng thực tế là nó ' s a constructor dẫn tôi tin rằng tôi có thể ghi đè lên nó và cung cấp một chữ ký phương thức khác, vì nó hoàn toàn được biết tại thời gian biên dịch loại đối tượng là gì.
Sự cố này sẽ biến mất nếu tôi thay đổi Shape
để không còn mở rộng NSObject
. Tuy nhiên, do việc đưa vào mã Objective-C hiện tại, nó cần phải mở rộng NSObject
.
Làm cách nào để cập nhật bản sao của bản sao của tôi để cho phép Shape
biết nó đang sao chép từ Shape
và cho phép Square
biết nó đang sao chép từ Square
?
Cảm ơn Rob - câu trả lời chắc chắn. –
Bạn cũng có thể thấy thảo luận này hữu ích về việc tạo bản sao trong Swift thuần túy: http://stackoverflow.com/questions/25645090/protocol-func-returning-self –
Đối với Swift 2/Xcode 7, nó sẽ là 'let theCopy = self. dynamicType.init() ', và dĩ nhiên' as! 'thay vì' as' (chỉ đề cập đến, bởi vì một câu hỏi liên quan xuất hiện ở đây: http://stackoverflow.com/questions/31885231/using-object-initializers-in- swift-to-replace-allocwithzone). –