一尘不染

覆盖Swift中的存储属性

swift

我注意到编译器不会让我用另一个存储的值覆盖存储的属性(这似乎很奇怪):

class Jedi {
    var lightSaberColor = "Blue"
}


class Sith: Jedi {
    override var lightSaberColor = "Red" // Cannot override with a stored property lightSaberColor
}

但是,我可以使用计算属性来执行此操作:

class Jedi {
    let lightSaberColor = "Blue"
}


class Sith: Jedi {
    override var lightSaberColor : String{return "Red"}

}

为什么不允许我再给它一个值?

为什么用存储的属性覆盖是可憎的,而要使用计算的一个犹太洁食呢?他们在想什么呢?


阅读 243

收藏
2020-07-07

共1个答案

一尘不染

为什么不允许我再给它另一个值?

绝对可以为继承的属性赋予不同的值。如果您在采用该初始值的构造函数中初始化属性,然后传递与派生类不同的值,则可以执行此操作:

class Jedi {
    // I made lightSaberColor read-only; you can make it writable if you prefer.
    let lightSaberColor : String
    init(_ lsc : String = "Blue") {
        lightSaberColor = lsc;
    }
}

class Sith : Jedi {
    init() {
        super.init("Red")
    }
}

let j1 = Jedi()
let j2 = Sith()

println(j1.lightSaberColor)
println(j2.lightSaberColor)

覆盖属性与为其赋予新值并不相同,它更像是为一个类赋予不同的属性。实际上,这就是在重写计算属性时发生的情况:在基类中计算该属性的代码
在派生类中计算该属性的重写的代码替换。

[是否]有可能覆盖实际的存储属性,即lightSaberColor具有其他行为?

除了观察者之外,存储的属性没有行为,因此实际上没有任何东西可以覆盖。通过上述机制可以为属性提供不同的值。这确实使用不同的语法来完成问题中的示例所要实现的目标。

2020-07-07