【问题标题】:Generic class doesn't call overridden initializer泛型类不调用重写的初始化程序
【发布时间】:2014-11-21 18:19:52
【问题描述】:
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

【问题讨论】:

标签: swift


【解决方案1】:

这看起来像一个编译器错误

如果你尝试:

NSStringFromClass(t.dynamicType)

它(游乐场)输出如下内容:

__lldb_expr_781.A

所以tA 类型。更有趣的是:

let t: B = coll.create()

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

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

var x = 0

如果您尝试访问它:

t.x

报告了运行时错误 (EXC_BAD_ACCESS)。

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

【讨论】:

【解决方案2】:

您需要创建初始化器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()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-25
    • 2016-08-25
    • 1970-01-01
    • 2019-10-06
    • 1970-01-01
    • 1970-01-01
    • 2016-04-11
    • 1970-01-01
    相关资源
    最近更新 更多