Generic 子类化的类
•浏览 1
Generic on class that is subclassed
在我用 Swift 编写的应用程序中,我有以下类结构。 A 类有一个静态方法,它可以做一些事情,但在一个非常简单的形式中,它看起来像下面的代码。
class A {
class func create<T: A>() -> T? {
println(NSStringFromClass(T));
return nil;
}
}class B : A {
}var myVar:B? = B.create();class A {
required init() {}
class func create() -> Self {
return self()
}
func test() -> String {
return"A"
}
}
class B : A {
override func test() -> String {
return"B"
}
}
let b = B.create() //"{A}" according to the playground, but it is a"B" instance!
b.test() //"B"protocol Entity {
init()
class func entityName() -> String
}
class EntityFactory<T : Entity> {
class func newEntity() -> T? {
var entity: T?
// ... create entity here using T.entityName()
return entity
}
}
class Person : Entity {
required init() {}
class func entityName() -> String {
return"Person"
}
}
let person = EntityFactory<Person>.newEntity()
类 B 是类 A 的子类。
class A {
class func create<T: A>() -> T? {
println(NSStringFromClass(T));
return nil;
}
}class B : A {
}var myVar:B? = B.create();class A {
required init() {}
class func create() -> Self {
return self()
}
func test() -> String {
return"A"
}
}
class B : A {
override func test() -> String {
return"B"
}
}
let b = B.create() //"{A}" according to the playground, but it is a"B" instance!
b.test() //"B"protocol Entity {
init()
class func entityName() -> String
}
class EntityFactory<T : Entity> {
class func newEntity() -> T? {
var entity: T?
// ... create entity here using T.entityName()
return entity
}
}
class Person : Entity {
required init() {}
class func entityName() -> String {
return"Person"
}
}
let person = EntityFactory<Person>.newEntity()
现在,当我执行以下代码时,println 命令输出 A 而不是 B。
class A {
class func create<T: A>() -> T? {
println(NSStringFromClass(T));
return nil;
}
}class B : A {
}var myVar:B? = B.create();class A {
required init() {}
class func create() -> Self {
return self()
}
func test() -> String {
return"A"
}
}
class B : A {
override func test() -> String {
return"B"
}
}
let b = B.create() //"{A}" according to the playground, but it is a"B" instance!
b.test() //"B"protocol Entity {
init()
class func entityName() -> String
}
class EntityFactory<T : Entity> {
class func newEntity() -> T? {
var entity: T?
// ... create entity here using T.entityName()
return entity
}
}
class Person : Entity {
required init() {}
class func entityName() -> String {
return"Person"
}
}
let person = EntityFactory<Person>.newEntity()
我不确定我在这里做错了什么,但我希望它输出 B.
在create方法中调试和放置断点时,$swift.type.T的值被定义为Builtin.RawPointer MyApp.A而不是B。
您在 A 上的通用类方法对我来说没有意义。相反,我实际上会使用类似下面的代码。这样它会创建一个 Self 的实例,它是你调用它的任何类。在这种情况下不需要泛型。
class A {
class func create<T: A>() -> T? {
println(NSStringFromClass(T));
return nil;
}
}class B : A {
}var myVar:B? = B.create();class A {
required init() {}
class func create() -> Self {
return self()
}
func test() -> String {
return"A"
}
}
class B : A {
override func test() -> String {
return"B"
}
}
let b = B.create() //"{A}" according to the playground, but it is a"B" instance!
b.test() //"B"protocol Entity {
init()
class func entityName() -> String
}
class EntityFactory<T : Entity> {
class func newEntity() -> T? {
var entity: T?
// ... create entity here using T.entityName()
return entity
}
}
class Person : Entity {
required init() {}
class func entityName() -> String {
return"Person"
}
}
let person = EntityFactory<Person>.newEntity()
请注意,A 需要一个必需的初始化程序,因为使用了 Self。在 Playground 中执行此操作时,创建的实例在右侧显示为 {A}。我相信这是 Xcode 中的错误,实际类型是正确的。
编辑:
我相信上面的代码不是您想要的,现在我确实得到了您想要做的。我建议不要根据实际的类名来这样做,而是使用泛型类为您创建实例:
class A {
class func create<T: A>() -> T? {
println(NSStringFromClass(T));
return nil;
}
}class B : A {
}var myVar:B? = B.create();class A {
required init() {}
class func create() -> Self {
return self()
}
func test() -> String {
return"A"
}
}
class B : A {
override func test() -> String {
return"B"
}
}
let b = B.create() //"{A}" according to the playground, but it is a"B" instance!
b.test() //"B"protocol Entity {
init()
class func entityName() -> String
}
class EntityFactory<T : Entity> {
class func newEntity() -> T? {
var entity: T?
// ... create entity here using T.entityName()
return entity
}
}
class Person : Entity {
required init() {}
class func entityName() -> String {
return"Person"
}
}
let person = EntityFactory<Person>.newEntity()
认为这是一个更优雅的解决方案,它将创建实体的责任转移到一个单独的泛型类中。这会产生可维护和可测试的代码。您甚至可以将其进一步抽象出来用于单元测试目的,但这似乎有点超出范围。