计算属性不直接存储值,而是提供一个 getter 和一个可选的 setter,来间接获取和设置其他属性或变量的值。
基本语法
class \ struct \ enum 类型名{
var 计算属性名:属性数据类型{
get{
return 计算后的属性值
}
set(新属性值){
}
}
}
代码示例:
class Rect {
var width = 10
var height = 0
var y :Int{
get{
return self.height
}
set(newY){
self.height = newY
}
}
var area :Int{
get{
return width * height
}
}
}
var rect = Rect()
rect.y = 30 //调用y的set方法
print(rect.area) //调用area的get方法
便捷 setter 声明
如果计算属性的 setter 没有定义表示新值的参数名,则可以使用默认名称newValue
所以上面计算属性 y 的set方法可以简写为:set{
self.height = newValue
}
只读计算属性
只有 getter 没有 setter 的计算属性就是只读计算属性。只读计算属性总是返回一个值,可以通过点运算符访
问,但不能设置新的值。
只读计算属性的声明可以去掉get 关键字和花括号:
所以上面的只读计算属性 area 可以简写为: var area :Int{
return width * height
}
属性观察者
属性观察者,监听和相应属性值的变化,每次属性被设置值的时候都会调用属性观察者。
可以为除了延迟存储属性之外的其他存储属性添加属性观察器,也可以通过重载属性的方式为继承的属性(包括存储属性和计算属性)添加属性观察器
不需要为非重载的计算属性添加属性观察器,因为可以通过它的 setter 直接监控和响应值的变化。
可以为属性添加如下的一个或全部观察者:
willSet 在新的值被设置之前调用。观察者会将新的属性值作为常量参数传入,在willSet 的实现代码中可以为这个参数指定一个名称,如果不指定则使用默认名称newValue 。
didSet 在新的值被设置之后立即调用。 观察者会将旧的属性值作为参数传入,可以为该参数命名或者使用默认参数名oldValue 。
class Person{
var name:String = ""{
willSet(newName){
print("name 将被设置为\(newName)")
}
didSet{
print("name设置完毕")
}
}
}
//var per = Person()
//per.name = "张三"
class Boy :Person {
var age: Int = 0{
willSet(newAge){
print("age 将被设置为 \(newAge)")
}
didSet{
print("age 设置完毕 原来的age为\(oldValue)")
}
}
}
var zs = Boy()
zs.name = "张三"
zs.age = 10
注意:
父类的属性在子类的构造器中被赋值时,它在父类中的willSet 和didSet 观察器会被调用。
如果在一个属性的didSet 观察器里为它赋值,这个值会替换该观察器之前设置的值。