Swift中属性的用法比objective-c中属性的用法丰富了很多。下面我逐一介绍。
Demo如下:
class Dog { var name = "旺财" init(){ println("狗被初始化了") } } class Person { let age = 20 var name = "Jack" var height = 0.0 lazy var dog = Dog() } var p = Person() p.dog
代码中,定义了Dog和Person两个类。
1. Dog中的name属性和Person中的age,name,height均为存储属性,用来存储对象的普通属性值。
2. Person中的dog属性,它也是存储属性,只不过它的属性值是Dog对象,而dog属性前面又有了lazy关键字修饰,它就成为了延迟存储属性。
3. 延迟存储属性:第一次用到的时候才初始化,不能作用于常量上面,一般作用于对象上面。上面代码 var p = Person()执行完毕后,dog属性并没有被初始化。当执行完p.dog后,dog才被初始化一个Dog对象。
二、 计算属性
Swift中的计算属性,很类似与C#中的get;set;属性。
Demo如下(计算正方形周长);
class Square { var width: Double = 10 var grith: Double { get{ return width * 4 } set{ width = newValue / 4 } } } var s = Square() s.width // 10 s.grith // 40 s.grith = 100 // width : 25
上例中,width表示正方形的边长,它是存储属性;而grith表示正方形的周长,它是计算属性;而grith这个计算属性中有get和set两个方法,get表示根据边长可以计算出周长;而set表示根据周长可以计算出边长。需要说明的是set方法中的newValue就是外界赋值给girth传递过来的值,比如上面的s.grith = 100 执行后,newValue的值就是100;而这个newValue值是系统默认的变量,我们也可以自己定义变量,如下:
class Square { var width: Double = 10 var grith: Double { get{ return width * 4 } set(myValue){ width = myValue / 4 } } }
注:存储属性必须对属性进行数据初始化操作(除非使用了构造方法,下一节进行讲解);而计算属性可以借助存储属性进行一些计算操作,而得到最终的结果。
三、 类型属性1. 只能是计算属性。
2. 不管创建多少个实例,这些实例共享一份资源。
class Square { class var PI: Double{ return 3.14 } } println("PI的值:\(Square.PI)")
如上例中,PI就是类型属性,它是用class关键字修饰的。并且调用的时候,直接"类名.属性名" 就可以了。而上述中的类型属性是简写形式,我们也可以写成:
class Square { class var PI: Double{ get{ return 3.14 } } }四、 属性监视器
1. 如果是计算属性,直接在set方法中监听即可,类似于objective-c中的kvo方式监听属性。
2. 如果是存储属性,我们需要使用willSet和didSet进行监视。
Demo如下:
class Square { var width: Double = 0.0 { willSet{ println("New Value:\(newValue),Current Value:\(width)") } didSet{ println("Old Value:\(oldValue),Current Value:\(width)") } } } var s = Square() s.width = 100
willSet和didSet在属性初始化过程中不会被调用。当执行到代码s.width = 100 的时候,会触发willSet和didSet这两个方法,最终结果为:
New Value:100.0,Current Value:0.0
Old Value:0.0,Current Value:100.0
五、属性重写
class Animal { var speed: Int { get { return 100 } } } class Dog: Animal { override var speed: Int { get { return 300 } set { } } }
不可以将一个继承来的读写属性重写为一个只读属性(下面的代码,Dog类会报错)
class Animal { var speed: Int { get { return 100 } set { } } } class Dog: Animal { override var speed: Int { get { return 100 } } }
存储属性的重写(最终属性的值是存储在父类中的)
class Animal { var speed: Int = 0 { willSet { println("Animal - willSet") } didSet { println("Animal - didSet") } } } class Dog: Animal { override var speed: Int { willSet { println("Dog - willSet") } didSet { println("Dog - didSet") } } } var d = Dog() d.speed = 10 最终打印结果 Dog - willSet Animal - willSet Animal - didSet Dog - didSet