1、存储属性
1. 作为特定类或结构实例的一部分,存储属性存储着常量或者变量的值。
存储属性可分为变量存储属性(keywordvar描写叙述)和常量存储属性(keywordlet描写叙述)。
struct student{
let name = ""
var score = 0
}
let a = student(name:"小笨狼",score:96)
注意:
① 定义储存属性时。须要为每个属性定义一个默认值。在初始化的时候,能够设置属性的初始值
② 对于结构当用let创建一个常量实例时(如let a)。这个实例中的属性将不可改变。即使属性是变量属性(a中的score属性也不可改变)。
这是由于结构是值类型。
当一个值类型实例作为常量而存在。它的全部属性也作为常量而存在。可是这个特性对类并不适用,由于类是引用类型
2. 懒惰储存属性
懒惰存储属性是当它第一次被使用时才进行初值计算。通过在属性声明前加上@lazy来标识一个懒惰存储属性。
当属性初始值由于外部原因,在实例初始化完毕之前不能够确定时,就要定义成懒惰存储属性。当属性初始值须要复杂或高代价的设置,在它须要时才被赋值时,懒惰存储属性就派上用场了。
class student{
let name = ""
@lazy var score = 0
}
var a = student() //这时候score还为被创建
a.score = 98 //score第一次使用时才会被创建
println(a.score) //输出:98
注意:
① 懒惰存储属性必须是变量属性(var定义的属性),由于它的初始值直到实例初始化完毕之后才被检索。常量属性在实例初始化完毕之前就应该被赋值,因此常量属性不能够被声明为懒惰存储属性。
假设声明。编译器会报错
2. 计算属性
1. 基本操作
除了存储属性。类、结构和枚举能够定义计算属性。计算属性并不存储值。它提供getter和可选的setter来间接地获取和设置其他的属性和值。
struct XSize{
var xOrigin:Float = 0
var length:Float = 0
}
class test{
var size = XSize()
var center:Float{
get{
return size.xOrigin + size.length/2
} //get方法。获取值
set(newSize){
size.xOrigin = newSize - size.length/2
} //set方法,存储值
}
}
如上面样例所看到的,center并不存储值,仅仅是提供getter和可选的setter来间接地获取和设置其他的属性和值。
2.setter声明的简略写法
假设计算属性的setter方法没有将被设置的值定义一个名称。将会默认地使用newValue这个名称来取代。
class test{
var size = XSize()
var center:Float{
get{
return size.xOrigin + size.length/2
} //get方法,获取值
set{
size.xOrigin = newValue - size.length/2
} //set方法,存储值
}
}
3. 仅仅读计算属性
仅仅读计算属性仅仅带有一个getter方法,通过点操作符。能够放回属性值,可是不能改动它的值。
class test{
var size = XSize()
var center:Float{
get{
return size.xOrigin + size.length/2
} //get方法,获取值
}
}
能够通过移除getkeyword和它的大括号。简化仅仅读计算属性的定义:
class test{
var size = XSize()
var center:Float{
return size.xOrigin + size.length/2
} //get方法,获取值
}
注意:
① 计算属性(包括仅仅读计算属性)应该使用varkeyword,由于它们的值并非固定的。
letkeyword仅仅被常量属性说使用。假设使用let定义。编译器将会报错
② 使用计算属性一定要声明类型,否则编译器会报错
3. 属性观察者
属性观察者观察属性值的改变并对此做出响应。
当设置属性的值时,属性观察者就被调用。即使当新值同原值同样时也会被调用。
除了懒惰存储属性。你能够为不论什么存储属性加上属性观察者定义。
另外。通过重写子类属性,也能够继承属性(存储或计算)加上属性观察者定义。属性重写在“重写”章节定义。
class student{
var name:String = "abc"{
willSet(newName){
println("will set new:\(newName)") //输出:will set new:小笨狼
}
didSet(oldName){
println("did set new:\(name),old:\(oldName)") //输出:did set new:小笨狼,old:abc
}
}
}
let a = student()
a.name = "小笨狼"
注意:
① 对属性加入观察者必须声明属性类型,否则编译器报错
② willSet能够带一个newName的參数,假设不这种话,这个參数就默认地被命名成newValue。
③ didSet也能够带一个oldName的參数,表示旧的属性,假设不带。这个參数默认命名为oldValue
④ 属性初始化时。willset和didSet并不会被调用。仅仅有在初始化上下文之外,当设置属性值时才被调用
⑤ willSet和didSet每次设置属性值时都会被调用,即使是设置的值和原来值同样
4. 全局和局部变量
以上所写的关于计算与观察属性值的特性同样适用于全局和局部变量。
全局变量是在不论什么函数、方法、闭包、类型上下文外部定义的变量。而局部变量是在函数、方法、闭包中定义的变量。
前面章节所遇到过的全局、局部变量都是存储变量。和存储属性一样,存储变量为特定类型提供存储空间而且能够被訪问
可是。你能够在全局或局部范围定义计算变量和存储变量观察者。计算变量并不存储值,仅仅用来计算特定值,它的定义方式与计算属性一样。
注意:
全局常量和变量一般是延迟计算的,跟懒惰存储属性一样,可是不须要加上@lazy。而局部常量与变量不是延迟计算的。
5. 类型属性
实例属性是特定类型实例的属性。当创建一个类型的实例时,这个实例有自己的属性值的集合,这将它与其他实例区分开来。
也能够定义属于类型本身的属性,即使创建再多的这个类的实例。这个属性也不属于不论什么一个。它仅仅属于类型本身,这种属性就称为类型属性。
1. 类型属性定义
对值类型而言。定义类型属性使用statickeyword,而定义类类型的类型属性使用classkeyword。
以下的样例展示了存储和计算类型属性的使用方法:
struct Student{
static var name = ""
static var score:Int{
return 0
}
}
class School{
class var name:String{
return "NB小学"
}
}
注意:
上面的样例是针对仅仅读计算类型属性而言的,只是你也能够像计算实例属性一样定义可读可写的计算类型属性
2. 查询与设置类型属性
像实例属性一样,类型属性通过点操作符来查询与设置。可是类型属性的查询与设置是针对类型而言的,并非针对类型的实例。比如:
Student.name = "小笨狼"
println(Student.name) //输出:小笨狼
println(School.name) //输出:NB小学
重点:
通过类的名称来訪问属性