我想创建一个具有静态属性的类,子类可以覆盖该属性,该属性将用于初始化实例。到目前为止,我已经尝试完成以下操作:
import Cocoa
class A: NSObject {
class var staticProperty: String {
return "A"
}
var property: String = A.staticProperty
}
class B: A {
override class var staticProperty: String {
return "B"
}
}
这不起作用,因为B().property
仍返回"A"
。如何更改此代码,以使property
包含子类指定的值?任何帮助将不胜感激!
修改
我想用property
的值初始化staticProperty
,所以它也可能像这样:
var property: SomeClass = SomeClass(A.staticProperty)
但是,此初始化仍应将"A"
用于类A,并将"B"
用于类B。
编辑2(在@RakeshaShastri发表评论之后)
对于我的特定用例,我需要property
进行存储(以便不进行计算)并且不延迟。
编辑3 简而言之,我正在尝试构建一个Realm模型类,该模型类与其他模型之间存在许多关系。对于这些模型(它们非常相似),我试图创建一个包含共享功能的超类,其中还包括反向关系。因此,我想拥有一个静态属性,该属性包含第一个模型中其他任何一个模型的键,然后使用该键名初始化LinkingObjects属性。由于Realm不允许延迟或计算,因此我不能在这里使用这些功能。
答案 0 :(得分:0)
如果您继承自NSObject,为什么不使用它呢?
import Cocoa
class A: NSObject {
var property: String
public override init() {
let str = type(of: self).perform(#selector(getter: type(of: self).staticProperty))?.takeUnretainedValue() as! String
property = str
}
@objc class var staticProperty: String {
return "A"
}
}
class B: A {
override class var staticProperty: String {
return "B"
}
}
答案 1 :(得分:0)
您可以使用此方法
class A {
var prop: String{
return "A"
}
}
class B: A {
override var prop: String{
return "B"
}
}
print(A().prop) // "PRINTS A"
print(B().prop) // "PRINTS B"
答案 2 :(得分:0)
A.staticProperty
将使用静态分派,并且将始终指向A
的class属性。这里需要动态调度,也就是type(of: self)
。
但是,self
需要一个实例来使用,因此var property: String = type(of: self.staticProperty
无法编译。
但是,惰性属性可以解决此限制,因此您可以将property
声明为惰性属性:
class A: NSObject {
class var staticProperty: String {
return "A"
}
private(set) lazy var property: String = { type(of: self).staticProperty }()
}
class B: A {
override class var staticProperty: String {
return "B"
}
}
print(B().property) // B
P.S。 private(set)
部分只是我通常要做的事情,我很少允许外部因素来更改我的对象。
更新正如@MartinR所指出的,懒惰不是OP的选择。不使用惰性变量的替代解决方案是使用“ shadowing”属性:
class A: NSObject {
class var staticProperty: String {
return "A"
}
private var _property: String?
var property: String {
get {
return _property ?? type(of: self).staticProperty
}
set {
_property = newValue
}
}
}
class B: A {
override class var staticProperty: String {
return "B"
}
}
let b = B()
print(b.property) // B
b.property = "B'"
print(b.property) // B'