泛型类不会调用重写的初始化程序

时间:2014-10-24 21:53:14

标签: swift

class Gen<T: A> {
    func create() -> T {
        if T.self is B.Type {
            println("YES")
        }
        return T(id: "cool")
    }
}

class A {
    let id: String

    init(id: String) {
        self.id = id
        println("class A \(id)")
    }
}

class B: A {
    override init(id: String) {
        println("class B \(id)")
        super.init(id: id)
    }
}

let coll = Gen<B>()
let t = coll.create()

输出是 “是” “A级酷”

来自被覆盖的B.init没有输出。

这是编译器错误吗?我需要以不同的方式做吗?

Xcode 6.1

2 个答案:

答案 0 :(得分:2)

这看起来像编译器错误

如果您尝试:

NSStringFromClass(t.dynamicType)

它(游乐场)输出类似:

  

__ lldb_expr_781.A

所以t的类型为A。更有趣的是:

let t: B = coll.create()

不会产生任何编译错误,但它是一个巨大的编译错误,因为如果实例的类型为A,则无法将其分配给B类型的变量(因为BA的子类,但由于多态性,可能相反。

要证明:将任何属性添加到B类,例如:

var x = 0

如果您尝试访问它:

t.x

报告运行时错误(EXC_BAD_ACCESS)。

另请阅读this Q/A,这是一个类似的问题(如果不一样)

答案 1 :(得分:0)

您需要创建初始值设定项required,然后将let realType = T.self行添加到create()方法,并将T()替换为realType()

class Gen<T: A> {
    func create() -> T {
        let realType = T.self
        return realType(id: "cool")
    }
}

class A {
    let id: String

    required init(id: String) {
        self.id = id
        println("class A \(id)")
    }
}

class B: A {
    required init(id: String) {
        println("class B \(id)")
        super.init(id: id)
    }
}

let coll = Gen<B>()
let t = coll.create()