如何在Swift中覆盖存储属性的setter?
在Obj-C中,我可以覆盖它的setter,但是Swift似乎并不满意将getter / setter用于存储属性。
假设我有一个名为Card
的{{1}}类。我不希望客户端给它任何无效值,因此,在objective-C中,我可以覆盖rank
以便它执行额外的检查。但是,Swift中的setRank
似乎没有帮助,因为willSet
是常量,分配newValue
没有意义,因为将在循环中调用setter。
答案 0 :(得分:106)
确定。通过Swift上的Apples文档阅读我发现了this:
如果为自己的didSet观察者中的属性赋值, 您指定的新值将替换刚刚设置的值。
所以你要做的就是:
var rank: Int = 0 {
didSet {
// Say 1000 is not good for you and 999 is the maximum you want to be stored there
if rank >= 1000 {
rank = 999
}
}
}
答案 1 :(得分:35)
您无法覆盖get
/ set
存储的属性,但您可以使用属性观察者willSet
/ didSet
:
var totalSteps: Int = 0 {
willSet(newTotalSteps) {
println("About to set totalSteps to \(newTotalSteps)")
}
didSet {
if totalSteps > oldValue {
println("Added \(totalSteps - oldValue) steps")
}
}
}
newValue
的默认参数名称为willSet
,oldValue
的默认参数名称为didSet
,您也可以在willSet(newTotalSteps)
中自行命名。
答案 2 :(得分:9)
如果你不想使用带有属性值暂时错误的问题的didSet,你应该在它周围包装一个计算属性。
package bankapplication;
import java.util.Scanner;
public class mainmenu {
static Scanner in = new Scanner(System.in);
public void main() {
createanaccount accountObject = new createanaccount();
viewaccount viewObject = new viewaccount();
System.out.println("Select an option");
System.out.println("1\t Create an account");
System.out.println("2\t View an account");
System.out.println("3\t Quit");
int option = in.nextInt();
switch (option) {
case 1: accountObject.createanaccount() ; {
}
case 2: viewObject.viewaccount() ;{
}
case 3: System.exit(3); {
}
}
}
}
或者:
private var _foo:Int = 0
var foo:Int {
get {
return _foo
}
set {
if(newValue > 999) {
_foo = 999
} else {
_foo = newValue
}
}
}
答案 3 :(得分:8)
get和set用于计算属性(它们没有任何后备存储)。 (在我看来,关键字'var'在这里令人困惑)
答案 4 :(得分:-7)
class Shape {
var sideLength: Double {
get {
return self.sideLength
}
set {
// Implement the setter here.
self.sideLength = newValue
}
}
}
在此示例中查看perimeter
。
摘自:Apple Inc.“The Swift Programming Language。”iBooks。 https://itun.es/us/jEUH0.l
class EquilateralTriangle: NamedShape {
var sideLength: Double = 0.0
init(sideLength: Double, name: String) {
self.sideLength = sideLength
super.init(name: name)
numberOfSides = 3
}
var perimeter: Double {
get {
return 3.0 * sideLength
}
set {
sideLength = newValue / 3.0
}
}
override func simpleDescription() -> String {
return "An equilateral triagle with sides of length \(sideLength)."
}
}
var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
triangle.perimeter
triangle.perimeter = 9.9
triangle.sideLength”