在Swift中,假设我想添加一个返回实例的静态工厂方法:
class MyClass {
static func getInstance() {
return MyClass(someProperty);
}
}
但是如果我不想写类名怎么办?对于静态方法和属性,是否有等效的self
?
同样的想法,如果我想从静态方法调用另一个静态方法:
class MyClass {
static func prepare(){
//Something
}
static func doIt() {
MyClass.prepare();
}
}
我可以在不明确使用MyClass
的情况下执行此操作吗?
答案 0 :(得分:4)
self也适用于静态方法,如下所示:
class MyClass {
static func prepare(){
print("Hello");
}
static func doIt() {
self.prepare();
}
}
答案 1 :(得分:0)
正如RobberR上面所写,您可以使用self
来访问self
的静态函数,并使用self.init(...)
作为工厂示例。请注意,您仍必须在工厂方法中将MyClass
指定为返回类型。
作为替代方案,更通用的方法,您可以让您的类符合工厂协议,该协议包含工厂方法的默认实现。这样,静态工厂方法不依赖于任何特定类,但是可以由符合工厂协议的任何类访问(以及用于公共初始化程序的附加帮助协议)。
出厂设置:
protocol FactoryInitializers {
var commonProperty : Int { get set }
init(commonProperty: Int)
}
protocol FactoryMethods {
typealias T: FactoryInitializers
static var defaultStaticCommonProperty : Int { get }
}
extension FactoryMethods {
static func getInstance() -> T {
return T(commonProperty: defaultStaticCommonProperty)
}
static func getInstanceFor(commonProperty commonProperty: Int) -> T {
return T(commonProperty: commonProperty)
}
}
protocol Factory : FactoryMethods, FactoryInitializers { }
示例类一致性:
class MyClass : Factory {
typealias T = MyClass
static var defaultStaticCommonProperty : Int = 1
var commonProperty : Int = 0
required init(commonProperty: Int) {
self.commonProperty = commonProperty
}
}
class MyOtherClass : Factory {
typealias T = MyOtherClass
static var defaultStaticCommonProperty : Int = 10
var commonProperty : Int = 0
required init(commonProperty: Int) {
self.commonProperty = commonProperty
}
}
使用示例:
var foo = MyClass.getInstance()
print(foo.dynamicType) // "MyClass"
print(foo.commonProperty) // 1
foo = MyClass.getInstanceFor(commonProperty: 5)
print(foo.commonProperty) // 5
var bar = MyOtherClass.getInstance()
print(bar.dynamicType) // "MyOtherClass"
print(bar.commonProperty) // 10
答案 2 :(得分:0)
您可以定义协议并使用swift generics,如下所示:
protocol Vehicle {
init()
}
class MyVehicleFactory<T:Vehicle> {
static func getInstance() -> T {
return T()
}
}
复制代码的人可以这样做:
class Car : Vehicle {
required init() { }
}
let car = MyVehicleFactory<Car>.getInstance();