Swift开发——存储属性与计算属性
Swift语言开发者建议程序设计者多用结构体开发应用程序。在Swift语言中,结构体具有了很多类的特性(除类的与继承相关的特性外),具有属性和方法,且为值类型。所谓的属性是指结构体中的变量或常量,所谓的方法是指结构体中的函数。在结构体中使用属性和方法是因为:①匹别于结构体外部定义的变量和常量;②从面向对象程序设计的角度,结构体对应着现实世界的一个客观物体,描述这个物体的性质需要用到它的属性和方法;③结构体定义的常量或变量称为实例,实例内部的变量或常量成员称为属性,实例内部的函数成员称为方法,这种称谓比常规含义的变量、常量和函数更具有意义。
定义结构体需使用关键字struct,结构体名建议使用“大骆驼命名法”,即首字母大写且其中的完整英文单词的首字母也大写。结构体定义的实例名建议使用“小骆驼命名法”,即首字母小写且其中的完整英文单词的首字母大写。结构体是一种类型,其中定义的属性和方法的位置可任意放置,可以先定义属性,再定义方法;也可以先定义方法,再定义属性。典型的结构体定义形式如下:
上述代码定义了一个结构体类型,名称为Circle,具有一个属性radius和一个方法area。一般地,在结构体中定义属性时需要为属性赋初始值,或者使用初始化器为结构体的各个属性赋初始值。属性分为两种,一种为存储类型的属性,如上述的radius属性;另一种为计算类型的属性,这种属性的行为类似于方法,但是形式是属性。结构体为值类型,如果结构体中定义的方法修改了其中的属性,需要使用关键字mutating修饰该方法,这种方法将为属性创建临时存储空间,待方法执行完后,将临时存储空间的值赋回给需要修改的属性。 结构体定义的变量或常量称为实例,实例调用属性和方法时使用“实例.属性”或“实例.方法(实际参数列表)”的形式。除了属于实例的属性和方法外,还可以定义属于结构体的属性和方法,借助static关键字定义,使用形式“结构体名.属性”或“结构体名.方法(实际参数列表)”访问这类属性和方法。
01、存储属性与计算属性
在结构体中,属性有以下三种类型:
(1) 使用static定义的静态属性,称为结构体属性,这类属性采用“结构体名.结构体属性名”的方式访问,如程序段1的第26行所示;
(2) 存储属性,又可称为动态属性,在结构体中定义的常量和变量均属于存储属性,存储属性为实例属性,采用“实例名.存储属性名”的方式访问;
(3) 计算属性,也属于实例属性,采用“实例名.计算属性名”的方式访问,但是计算属性本身不保存属性值,与存储属性不同之处在于在定义计算属性后添加一对“{ }”,在其中添加get方法和set方法(至少要添加get方法),依次用于获取存储属性值或设置存储属性值。
对于存储属性:①当使用private修饰时将变成私有存储属性,这类私有存储属性只能借助计算属性间接访问,不能借助实例访问,从而实现了数据“封装”特性;②当使用lazy修饰时将变成惰性存储属性,这类惰性存储属性必须为变量类型,当它被首次使用时才初始化,即如果惰性存储属性只定义了但没有使用,则该属性不会占用存储空间。
程序段2详细介绍了存储属性、计算属性和私有存储属性的用法。
程序段2结构体的属性用法实例
程序段2的执行结果如图2所示。
■ 图2 程序段2的执行结果
下面结合图2介绍程序段2。在程序段2中,第3~6行定义了结构体Point,具有两个存储属性x和y。
第7~34行定义结构体Circle。其中第9行“var radius=1.0”定义存储属性radius,并赋初值为1.0。一般地,在结构体内定义存储属性时需给它们赋初值。第10~20行定义了计算属性r,将其代码再次罗列如下:
计算属性r更像是一个方法,具有“{ }”括起来的可执行代码。其中,第12~15行为get方法,这是一种程序员约定的名称,因为这种方法形如“get{ }”,get方法用于返回结构体中某个设定的存储属性的值,这里第14行返回存储属性radius的值,即读取r相当于读取radius。第16~19行为set方法,这也是一种程序员约定的名称,因为这种方法形式“set{ }”,set方法用于向某个选定的存储属性赋值,这里第18行向radius赋值,其中,newValue为关键字,自动保存赋给r的值,因此,向r赋值(即写r)就是向radius赋值(即写radius)。注意:①如果计算属性只有get方法,则去掉set部分,同时,get和“{ }”也可省略,如第22~25行的计算属性c,此时的计算属性为只读属性;②计算属性可以只有get方法,称为只读属性;可以同时有get方法和set方法,称为可读可写属性;但是不能只有set方法,即没有只写属性;③在set方法中可以使用newValue关键字,用于表示赋给计算属性的值,也可以自定义该量,例如第16~19行的代码可以替换为下述代码:
这里使用了自定义的val变量,此处无须指定数据类型,而是根据计算属性r的类型自动推断数据类型。
第21行“private var center=Point(x:0, y:0)”定义私有存储属性center,这类属性只能借助计算属性访问,同时这类属性可被结构内的其余属性和方法使用,但不能被结构体外部的方法调用,结构体定义的实例也不能访问这类属性。
第22~25行定义一个计算属性c,其代码再次罗列如下:
这里计算属性c为一个只读属性,省略了get和“{ }”,返回center的值,即读取c相当于读取center。
第26~29行定义了函数moveTo,使用了mutating关键字,因为该函数将修改私有存储属性center的值。第28行“center=point”将参数point赋给私有存储属性center。
第30~33行定义了函数area,返回值为Double类型,函数返回圆的面积。第32行“return 3.14*r*r”使用了计算属性r,因为计算属性r为可读可写属性,这里读取r相当于读取radius。
第36行“var circle=Circle()”定义结构体实例circle。第37行“circle.r=5.0”将5.0赋给实例circle的计算属性r,计算属性r并不保存值,其内部将5.0赋给存储属性radius。第38行“print("radius=\(circle.r)")”输出存储属性radius的值,得到“radius=5.0”。第39行“circle.moveTo(point:Point(x:3.0, y:4.0))”调用moveTo方法将圆心移动到点(3.0, 4.0)处。第40行“print("Circle at (\(circle.c.x),\(circle.c.y))",terminator:" ")”和第41行“print("with area:\(String(format:"%5.2f",circle.area()))")”联合输出“Circle at (3.0,4.0) with area:78.50”,其中,第40行通过只读的计算属性c,获取圆心坐标。
- 点赞
- 收藏
- 关注作者
评论(0)