如何在Swift子类中实现复制构造函数?

克雷格·奥蒂斯(Craig Otis)

我在Swift操场上有以下示例,试图在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}

问题在于这实际上并不能以当前形式进行编译。子类中init(copyFrom: Square)方法上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

如何更新我的复制构造函数,以允许aShape知道从a复制Shape,而允许aSquare知道从a复制Square

罗布·纳皮尔

init(copyFrom: Square)是的重载,而不是覆盖init(copyFrom: Shape)我的意思是,它们是不相关的方法,因为它们接受不同的类型。在Swift中这是可以接受的。在ObjC中,这是非法的。ObjC中没有重载。

Swift初始化器不会自动继承。因此,在Swift中,您无法尝试将random复制ShapeSquare初始化程序不可用。但是在ObjC中,初始化器自动继承(您不能阻止它们这样做)。因此,如果您有一个方法initWithCopyFrom:(*Shape),则要求每个子类都愿意接受它。这意味着您可以(在ObjC中)尝试创建一个Circle作为Square的副本。那当然是胡说八道。

如果这是NSObject子类,则应使用NSCopying这是您的处理方式:

import Foundation

class Shape : NSObject, NSCopying { // <== Note NSCopying
  var color : String

  required override init() { // <== Need "required" because we need to call dynamicType() below
    color = "Red"
  }

  func copyWithZone(zone: NSZone) -> AnyObject { // <== NSCopying
    // *** Construct "one of my current class". This is why init() is a required initializer
    let theCopy = self.dynamicType()
    theCopy.color = self.color
    return theCopy
  }
}

class Square : Shape {
  var length : Double

  required init() {
    length = 10.0
    super.init()
  }

  override func copyWithZone(zone: NSZone) -> AnyObject { // <== NSCopying
    let theCopy = super.copyWithZone(zone) as Square // <== Need casting since it returns AnyObject
    theCopy.length = self.length
    return theCopy
  }

}

let s = Square()      // {{color "Red"} length 10.0}

let copy = s.copy() as Square // {{color "Red"} length 10.0} // <== copy() requires a cast

s.color = "Blue"               // {{color "Blue"} length 10.0}
s                              // {{color "Blue"} length 10.0}
copy                           // {{color "Red"}

迅捷3

class Shape: NSObject, NSCopying {

    required override init() {
        super.init()
    }    

    func copy(with zone: NSZone? = nil) -> Any {
        let copy = type(of: self).init()
        return copy
    }

}

class Square: Shape {

    required override init() {
        super.init()
    }    

    func copy(with zone: NSZone? = nil) -> Any {
        let copy = super.copy(with: zone) as! Square
        copy.foo = self.foo
        ......
        return copy
    }

}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在Scala中为子类实现DRY复制构造函数?

来自分类Dev

如何实现子类的构造函数?

来自分类Dev

如何在子类构造函数中调用父构造函数?

来自分类Dev

如何在JavaScript中的构造函数中复制对象

来自分类Dev

Dart-如何在子类的构造函数中调用超类的工厂构造函数?

来自分类Dev

如何在构造函数中复制整个数组

来自分类Dev

如何在构造函数中复制整个数组

来自分类Dev

如何在Scala中实现OCaml / F#的“函数”构造?

来自分类Dev

如何在Scala中实现OCaml / F#的“函数”构造?

来自分类Dev

我如何在 kotlin 中实现类似 java 的构造函数

来自分类Dev

强制子类在C ++中实现某个构造函数原型

来自分类Dev

我们如何在C ++中从子类中调用父级重载的构造函数?

来自分类Dev

如何在Swift中完成工厂构造函数?

来自分类Dev

Java如何在调用父构造函数之前覆盖子类中的父类属性

来自分类Dev

如何在基类构造函数中为每个子类执行特定任务

来自分类Dev

用C ++中的链表实现堆栈,复制构造函数

来自分类Dev

父/子类的C ++复制构造函数问题

来自分类Dev

父/子类的C ++复制构造函数问题

来自分类Dev

如何在Codeigniter中将父类构造函数访问子类

来自分类Dev

如何在Swift中实现ROT13函数?

来自分类Dev

如何在函数中动态生成子类?

来自分类Dev

如何停止在子类中调用基类的构造函数

来自分类Dev

如何覆盖子类中的抽象类构造函数

来自分类Dev

私有构造函数如何在Java中实现发布安全

来自分类Dev

如何在运行时根据构造函数参数在超类中创建子类对象(在Java中)

来自分类Dev

如何在类的私有部分中为复制构造函数定义原型,以防止类的复制?

来自分类Dev

链表的复制构造函数的正确实现

来自分类Dev

如何在Perl中使'='调用复制构造函数?

来自分类Dev

如何在python中声明要在子类中实现的变量?

Related 相关文章

  1. 1

    如何在Scala中为子类实现DRY复制构造函数?

  2. 2

    如何实现子类的构造函数?

  3. 3

    如何在子类构造函数中调用父构造函数?

  4. 4

    如何在JavaScript中的构造函数中复制对象

  5. 5

    Dart-如何在子类的构造函数中调用超类的工厂构造函数?

  6. 6

    如何在构造函数中复制整个数组

  7. 7

    如何在构造函数中复制整个数组

  8. 8

    如何在Scala中实现OCaml / F#的“函数”构造?

  9. 9

    如何在Scala中实现OCaml / F#的“函数”构造?

  10. 10

    我如何在 kotlin 中实现类似 java 的构造函数

  11. 11

    强制子类在C ++中实现某个构造函数原型

  12. 12

    我们如何在C ++中从子类中调用父级重载的构造函数?

  13. 13

    如何在Swift中完成工厂构造函数?

  14. 14

    Java如何在调用父构造函数之前覆盖子类中的父类属性

  15. 15

    如何在基类构造函数中为每个子类执行特定任务

  16. 16

    用C ++中的链表实现堆栈,复制构造函数

  17. 17

    父/子类的C ++复制构造函数问题

  18. 18

    父/子类的C ++复制构造函数问题

  19. 19

    如何在Codeigniter中将父类构造函数访问子类

  20. 20

    如何在Swift中实现ROT13函数?

  21. 21

    如何在函数中动态生成子类?

  22. 22

    如何停止在子类中调用基类的构造函数

  23. 23

    如何覆盖子类中的抽象类构造函数

  24. 24

    私有构造函数如何在Java中实现发布安全

  25. 25

    如何在运行时根据构造函数参数在超类中创建子类对象(在Java中)

  26. 26

    如何在类的私有部分中为复制构造函数定义原型,以防止类的复制?

  27. 27

    链表的复制构造函数的正确实现

  28. 28

    如何在Perl中使'='调用复制构造函数?

  29. 29

    如何在python中声明要在子类中实现的变量?

热门标签

归档