在Swift中属性可以分为存储属性、计算属性和类型属性三种。
存储属性
存储属性就是存储特定类的一个常量或者变量。常量存储的属性使用let关键字定义,变量存储的属性使用var关键字定义
懒存储属性
Swift提供了所谓的懒存储属性,懒存储属性是指当被第一次调用的时候才会计算其初始值的属性,一个懒存储属性通过在属性声明的前面加上lazy来标示。
class PersonInfo
{
// PersonInfo是一个将外部文件中数据导入的类,这个类初始化需要消耗很多时间
var personFilseName = "personInfo.txt"
// 这里会提供数据导入功能
}
class PersonDataManager
{
lazy var personInfo = PersonInfo()
var data = String()
// 这里提供数据管理功能
}
let manager = PersonDataManager()
manager.data += "some data"
manager.data += "Some more data"
print(manager.data)
print(manager.personInfo.personFileName) // 此时PersonInfo的实例被创建
注意:
必须将存储属性声明成变量(使用var关键字),因为属性的值在实例构造完成之前可能无法得到。而常量属性在构造过程完成之前必须要有初始值。
计算属性
计算属性不存储值,而是提供了一个getter和setter来分别进行获取值和设置其他属性的值。getter使用get关键字进行定义,setter使用set关键字进行定义。
// 如果计算属性的setter方法没有将被设置的值定义一个名称,会默认使用newValue名称代替
class Person
{
var length:Int = 10
var age:Int
{
get
{
return length*2
}
set
{
length = newValue / 2
}
}
// 只读计算属性
var height:Int
{
get
{
return length*4
}
}
// 只读可以直接省略get
var height2:Int
{
return length*4
}
var person = Person()
person.height // 只读不可以赋值
}
注意:
计算属性必须使用var关键字定义,包括只读计算属性,因为它们的值是不固定的。
全局的常量或变量都是延迟计算的,跟延迟属性相似,不同的地方在于,全局的变量或常量不需要标记lazy特性;局部范围的常量或变量不会延迟计算。
属性观察器
属性观察器包括didSet和willSet,其中属性值改变前会触发willSet,属性改变后会触发didSet.
(1)给属性添加观察器必须要声明清楚属性类型,否则编译器报错。
(2)willSet可以带一个newName的参数,没有的话,该参数默认命名为newValue.
(3)didSet可以带一个oldName的参数,表示旧的属性,不带的话默认命名为oldValue.
(4)属性初始化时,willSet和didSet不会调用。只有在初始上下文之外,当设置属性值时才会调用。另外,在didSet的实现体内给属性赋值,也不会再次调用属性的。
(5)即使是设置的值和原来的值相同,willSet和didSet也会被调用。
class Person{
// 普通属性
var name:String?
var age:Int =0
{
// 在age属性发生改变之前做点什么
willSet
{
print("将要设置的值为\(newValue)")
}
// 在age属性发生变化之后,更新一下name这个属性
didSet
{
if age<10
{
name = "lucy"
}else
{
name = "lily"
}
print("\(name!)的年龄从 \(oldValue)改为\(age)")
}
}
}
let per = Person()
per.age = 0
per.age = 20
类型属性
类型属性与个体无关,不需要对类进行实例化就可以使用。
类型属性使用关键字static来定义,结构体、枚举和类都可以定义类型属性。
1.结构体类型属性的语法格式
struct 结构体名{
static var 存储属性 = “xxx”
static var 计算属性名:属性数据类型{
return 计算后属性值
}
}
2.枚举类型属性的语法格式
enum 枚举名 {
static var 存储属性 = “xxx”
static var 计算属性名:属性数据类型 {
return 计算后属性值
}
}
3.类类型属性的语法格式
class 类名 {
static var 存储属性 = “xxx”
static var 计算属性名:属性数据类型{
return 计算后属性值
}
class var 子类对父类实现支持重写:属性数据类型{
return 重写后属性值
}
}
在为类定义类型属性时,可以使用关键字class来代替static关键字。
结构体类型属性eg:
struct Student {
var livingCost:Double = 0.0
var owner:String = ""
static var tuition : Double = 11668
static var tuitionProp:Double{
return tuition + 100
}
var totalCost : Double{
return Student.tuition + livingCost
}
}
// 访问静态属性
print(Student.tuitionProp)
var aStudent = Student()
// 访问实例属性
aStudent.livingCost =1_000
// 访问实例属性
print(aStudent.totalCost)
枚举类型属性eg:
enum Student{
case iOS
case Java
case PHP
case nodes
static var tuition :Double = 11668
static var tuitionProp:Double{
return tuition
}
var instanceProp : Double{
switch(self){ // self指代当前实例本身
case iOS:
Student.tuition = 11667
case Java:
Student.tuition = 11669
case PHP:
Student.tuition = 11666
case nodejs:
Student.tuition = 11668
}
return Student.tuition + 1_000
}
}
// 访问静态属性
print(Student.tuitionProp)
var aStudent = Student.iOS
// 访问实例属性
print(aStudent.instanceProp)
类类型属性eg:
class Student {
var livingcost:Double = 0.0
var name:String = ""
static var tuition : Double = 11668
static var tuitionProp:Double{
return tuition
}
var totalCost : Double{
return Student.tuition + livingcost
}
}
// 访问静态属性
print(Student.tuition)
var aStudent = Student()
// 访问实例属性
aStudent.livingCost =1_000
// 访问实例属性
print(aStudent.totalCost)
注意:
跟实例的存储属性不同,类型的存储属性必须指定默认值。因为类型本身无法再初始化过程中使用构造器给类型属性赋值。
网友评论