SwiftNote-8
2016年05月06日 Swift

类的属性

相当于其他编程语言中的类成员变量,在Swift中叫做属性。

存储型属性

相当于普通成员,用于类实例中变量/常量,实例可以通过点号的方式来访问/修改

1
2
3
4
5
6
class Person
{
var name:String = ""
}
var p = Person()
p.name = "Jack"

name就是普通的存储属性,可以通过实例直接访问和修改,需要注意的是生成一个常量结构体实例,即使里面的存储属性是var定义的,也不能通过结构体实例来修改属性值,因为结构体是值类型

1
2
3
4
5
6
7
struct Test
{
var temp:Int32 = 0
}
let t = Test()
// 即使temp是变量,也不能用t.temp = 12来修改实例内的属性值
// t.temp = 12 这里直接报错

延迟存储属性,使用lazy关键字,表示此存储属性被访问的时候才会被求值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct LazyTest
{
var lazyVar = 12
}

class LazyDemoTest
{
lazy var lt = LazyTest()
var dict:[Int:String] = [:]
}
// 此时LazyDemoTest中的lt还没有创建出来
var ldt = LazyDemoTest()
// 这时lt才被计算创建
print(ldt.lt.lazyVar)

计算型属性

不能直接通过类,结构体,枚举实例来访问/修改的属性,但是提供了一个getter与一个可选的setter来访问和修改属性的值,这样的属性叫计算型属性。只有getter的叫只读属性,因为只能获取值,不能设置值。setter不设置新值的名字时默认使用newValue这个变量就可以访问新设置的值。计算型属性一定是var定义的,因为常量不可以修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import Cocoa
struct Cube
{
var len = 0.0
var area:Double{
get
{
return len * len
}
set(newArea) // 可以不设置新值名称,默认使用newValue
{
print("newValue = \(newArea)")
len = sqrt(newArea)
}
}
}

var cube = Cube(len: 10.0)
print(cube.area)
cube.area = 200
print(cube.len)

只读属性,甚至get还可以省略,直接大括号内返回语句就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Rect
{
var wid = 0.0, hgt = 0.0
var area:Double{
get
{
return wid * hgt
}
}
/*
// 可以省略掉get
var area:Double{
return wid * hgt
}
*/
}

var rect = Rect()
rect.hgt = 10
rect.wid = 12
print(rect.area)
//rect.area = 100 // 报错,只有get,没有setter,不能设置其值

属性观察器

就是在属性值设置之前/设置完被调用,这样就可以监控属性值的变化,分别用didSetwillSet,从名字上就能猜到功能。willSet传入将要设置的新值,不提供名称使用newValuedidSet传入旧的值(被设置之前的属性值),不提供名称使用oldValue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
struct Wallet
{
var totalMoney:Float = 0.0{
willSet
{
print("totalMoney = \(newValue) called from willSet")
}
didSet(haveMoney)
{
print("oldValue = \(haveMoney) called from didSet")
if totalMoney > haveMoney
{
print("Add \(totalMoney - haveMoney)")
}
// 如果在属性观察器里再次进行对本属性进行属性,这会替换掉之前设置的值
// totalMoney = 10.0 // 此时实例中的totalMoney已经变成了10
}
}
}

var wallet = Wallet(totalMoney: 100)
wallet.totalMoney = 120 // willSet和didSet都被调用
// 输出
// totalMoney = 120.0 called from willSet
// oldValue = 100.0 called from didSet
// Add 20.0

类型属性

也就是类型C++的静态成员变量,不属于实例,属性类级别所有,用类名来访问,Swift也相同,同样是用static关键字来定义,className.staticVarName方式来访问和修改,同样也支持计算属性,针对类而言,如果子类需要重写父类属性实现,需要使用class关键字来代替static关键字。

1
2
3
4
5
6
7
8
9
10
11
12
13
class StaticDemo
{
static var staticInt:Int = 0
static var staticString:String{
return "StaticString"
}
// 支持子类重写此属性
class var needOverrideVariable:Bool{
return false
}
}
StaticDemo.staticInt = 12
print(StaticDemo.staticString)