Swift覆盖实例变量

Dăn*_*ian 31 variables inheritance class ios swift

我知道这个答案已经在这里以其他形式发布了,但我想更多地了解在swift中覆盖实例变量.

假设我有这个代码

class BaseView:UIView{
 let someVariable:Int = 1
 // do some work with someVariable
}

class ExtendedView:BaseView{
 let someVariable:Int = 2
}
Run Code Online (Sandbox Code Playgroud)

好.从我读到的,常量需要一个覆盖前缀.其他答案说我应该宣布二传手和吸气剂?为什么?我真的不在乎那两个.我只需要替换值.我不能真正使用init覆盖,因为我继承自UIView,这可能是非常危险的(我认为).

欢迎任何建议.

Gri*_*mxn 63

如你所说,你不能简单地重新定义一个子类中的常量(毕竟它是一个常量).您得到的错误是"无法覆盖存储的属性".它似乎是可以覆盖一个var,但是,当我改变了let someVariablevar someVariable我碰到一个"暧昧使用'someVariable’的"当我在子类中访问它(注-同样的事情发生了,我是否使用override与否).

最简单的解决方案是使用吸气剂.这实际上是一个函数,因此您可以愉快地覆盖它,将为您管理支持变量,如果您不提供setter ...它将为每个类保持不变:

class BaseView: UIView {
    var someVariable: Int { get { return 1 } }
    // do some work with someVariable
}

class ExtendedView: BaseView {
    override var someVariable: Int { get { return 2 } }
}

let a = BaseView()
a.someVariable // 1
let b = ExtendedView()
b.someVariable // 2
Run Code Online (Sandbox Code Playgroud)

正如评论员@ user3633673指出的那样,如果你只有一个吸气剂(而不是一个二传手),你可以放弃get,但为了清晰起见,我把它留下了.没有它,这是一样的......

class BaseView: UIView {
    var someVariable: Int { return 1 }
    // do some work with someVariable
}

class ExtendedView: BaseView {
    override var someVariable: Int { return 2 }
}

let a = BaseView()
a.someVariable // 1
let b = ExtendedView()
b.someVariable // 2
Run Code Online (Sandbox Code Playgroud)

  • 对于一些读者,应该注意,在简单的只读计算属性中,"get"不是必需的.`var someVariable:Int {return 1}`是`var someVariable:Int {get {return 1}}`的简写. (9认同)