美文网首页Swift学习swift
swift面向对象特性——属性

swift面向对象特性——属性

作者: 阿凡提说AI | 来源:发表于2017-02-27 16:07 被阅读14次

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

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

    相关文章

      网友评论

        本文标题:swift面向对象特性——属性

        本文链接:https://www.haomeiwen.com/subject/tmkzwttx.html