swift面向对象特性——属性

在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)

注意:
跟实例的存储属性不同,类型的存储属性必须指定默认值。因为类型本身无法再初始化过程中使用构造器给类型属性赋值。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,295评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,928评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,682评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,209评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,237评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,965评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,586评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,487评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,016评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,136评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,271评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,948评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,619评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,139评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,252评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,598评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,267评论 2 358

推荐阅读更多精彩内容