我来自Java世界。现在,我正在使用Swift 4进行编程。
我想在Swift中实现抽象类,我知道在Swift中没有这样的抽象类概念。但是我知道我们可以通过使用协议在Swift中模仿这个概念。例如,这就是我尝试过的:
// With protocol, I can define functions that concrete class have to implement
protocol ProductProvider {
func getProductNumber() -> Int
}
// with protocol extension, I can define shared (computed) properties and functions among concrete classes that comply with this protocol
extension ProductProvider {
var maxProductCount: Int {
return 10
}
}
但是现在,我希望有一个可以设置并获取的共享变量(“共享”是指与符合该协议的类共享):
extension ProductProvider {
var maxProductCount: Int {
set(newValue) {
// set to what if I couldn't define private stored variable in extension to hold the most recent set value ?
}
get{
// how to return the most recent value set?
}
}
}
我的问题在上面代码的注释中。如何在Swift 4的协议扩展中进行设置并获取变量?如果不可能,有什么解决方法?
答案 0 :(得分:0)
除了讨论是否是实现所需目标的正确方法之外,还可以使用对象关联。
public final class ObjectAssociation<T: AnyObject> {
private let policy: objc_AssociationPolicy
/// - Parameter policy: An association policy that will be used when linking objects.
public init(policy: objc_AssociationPolicy = .OBJC_ASSOCIATION_RETAIN_NONATOMIC) {
self.policy = policy
}
/// Accesses associated object.
/// - Parameter index: An object whose associated object is to be accessed.
public subscript(index: AnyObject) -> T? {
get { return objc_getAssociatedObject(index, Unmanaged.passUnretained(self).toOpaque()) as! T? }
set { objc_setAssociatedObject(index, Unmanaged.passUnretained(self).toOpaque(), newValue, policy) }
}
}
在您的扩展程序中
extension SomeType {
private static let association = ObjectAssociation<NSObject>()
var simulatedProperty: NSObject? {
get { return SomeType.association[self] }
set { SomeType.association[self] = newValue }
}
}
不可能通过对象关联直接存储Swift类型。您可以存储例如NSNumber代替Int。
来源:https://stackoverflow.com/a/43056053/1811810
答案 1 :(得分:0)
我认为最简单的方法是使用getter和setter在协议中定义变量。然后,在您的conform对象中,应将变量声明为conformance。 一个例子:
protocol AbstractObject {
var maxProductCount: Int { get set }
}
struct ConformObject: AbstractObject {
var maxProductCount: Int
}
所以现在您可以在默认实现中使用变量
extension AbstractObject {
mutating func addOne() -> Int {
self.maxProductCount += 1
return 1
}
}