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
答案 0 :(得分:2)
这看起来像编译器错误。
如果您尝试:
NSStringFromClass(t.dynamicType)
它(游乐场)输出类似:
__ lldb_expr_781.A
所以t
的类型为A
。更有趣的是:
let t: B = coll.create()
不会产生任何编译错误,但它是一个巨大的编译错误,因为如果实例的类型为A
,则无法将其分配给B
类型的变量(因为B
是A
的子类,但由于多态性,可能相反。
要证明:将任何属性添加到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()