属性分为存储属性与计算属性,存储属性可以有默认值,计算属性则根据已有信息返回某种计算结果。类,结构体,枚举都可以有属性
基本存储属性
不使用代码获取值的属性都是基本存储属性,包括读写属性(var 声明)以及只读属性(let声明)
嵌套类型
和嵌套函数一样,类型也可以嵌套
class Person{
//身高
var height=170
//嵌套类型
enum Color{
case yellow
case black
case white
}
//颜色
var color=Color.black
}
惰性存储属性
有时候我们不能马上给存储属性赋值,只想当实际使用的时候才会赋值,那么就可以使用惰性存储属性,由于值会改变,所以惰性存储属性只能声明为var。
注意,惰性存储属性只会在第一次访问的时候才会调用内部代码计算
class Person{
//身高
var height=170
//嵌套类型
enum Size{
case Big
case Middle
case Small
}
//体型
lazy var size: Size = {
switch self.height {
case 0...150:
return Size.Small
case 151...170:
return Size.Middle
case 170...200:
return Size.Big
default:
return Size.Big
}
}()
}
计算属性
计算属性提供一个getter方法获取属性的值,并可选地提供一个setter方法设置属性的值
class Person{
//身高
var height=170
//嵌套类型
enum Size{
case Big
case Middle
case Small
}
//体型
var size: Size{
get{
switch self.height {
case 0...150:
return Size.Small
case 151...170:
return Size.Middle
case 170...200:
return Size.Big
default:
return Size.Big
}
}
set(newSize){
switch newSize {
case .Small:
height=100
case .Middle:
height=170
case .Big:
height=200
}
}
}
}
var person=Person()
print(person.size)//Middle
person.height=200
print(person.size)//Big
person.size = Person.Size.Small;
print(person.size)//Small
属性观察者
属性观察只对存储属性有用,可以用willSet观察属性即将发生的变化,使用didSet观察属性已经发生的变化。
class Person{
//身高
var height=170 {
willSet(newHeight){
print("height will change to \(newHeight)")
}
didSet(oldHeight){
print("height changed,old height is \(oldHeight)")
}
}
}
var person=Person()
person.height=200
//height will change to 200
//height changed,old height is 170
类型属性
类型属性和上一节介绍的类型方法一样,枚举和结构体可以通过static关键字来实现类型属性,类也可以通过static关键字实现类型属性,但是这样子类就不能覆盖父类的类型属性。如果希望子类能覆盖父类的类型属性,就需要用class关键字实现计算类型属性。
class Person{
//类型属性
static var height=170
//计算类型属性
class var color:String{
return "black"
}
}
class Worker:Person{
//重写类型属性
override class var color:String{
return "white"
}
}
print(Person.color)//black
print(Worker.color)//white
print(Worker.height)//170
print(Worker.height)//170
访问控制
swift提供5个访问层级对属性进行访问控制
访问层级 | 可见性 | 继承性 |
open | 所在模块,引入所在模块的模块 | 所在模块,引入所在模块的模块 |
public | 所在模块,引入所在模块的模块 | 所在模块 |
internal(默认值) | 所在模块 | 所在模块 |
fileprivate | 所在文件 | 所在文件 |
private | 所在作用域 | 所在作用域 |
如果属性既有读取方法,也有写入方法,可以单独为读写方法控制可见度
class Person{
//读取方法可见,写入方法私有
internal private(set) var height=170
}