说到结构体和类,仍是那句话,只要是接触过编程的小伙伴们对这二者并不陌生。但在Swift中的Struct和Class也有着使人眼前一亮的特性。Struct的功能变得更为强大,Class变的更为灵活。Struct中不只能够定义属性,而且还能够在其中定义函数,这一点比较像Class的特性了。不过Struct毕竟是结构体,它仍是不支持继承等类特有的属性的。今天这篇博客就正儿八经的来搞一搞Swift中的Struct和Class。html
固然,这篇博客是比较基础的,可是基础的东西才是重要的东西呢,废话很少说了,走起。编程
一. Struct (结构体)编程语言
结构体,说白了就是一组变量,这些变量有统一的命名。在Swift中,咱们不只能够在Struct中声明变量并为变量设置默认值,并且能够在Struct中添加相应的函数。接下来咱们就要建立一个Point结构体,里边有两个属性x坐标和y坐标,而且x坐标和y坐标的初始值为0。其中还有两个方法,一个是display方法,负责输出点的坐标,而且还有一个setPoint方法,这个方法负责设置坐标点。而后咱们就要去这个结构体去声明变量,而且调用其中的方法。函数
1.结构体类型的定义post
使用struct关键字来声明咱们的结构体类型,结构体类型的名称为MyPoint, 其中坐标x, y为变量,其初始值为0。而且为咱们的结构体添加了一个setMyPoint()方法和display()方法。url
由上面的代码片断你也许会注意到在setMyPoint()方法关键字func前边多了一个mutating关键字。在Struct中的函数,默认(不添加mutating关键字)的函数对Struct中属性只有只读权限。若是你添加上mutating, 那么该函数就对属性持有读写的权限。spa
2.结构体类型变量的声明以及结构体函数的使用3d
接下来咱们就利用上述“MyPoint”结构体类型来建立一个结构体类型变量。由于(x, y)值是有初始值的,因此在初始化结构体变量时不须要为其指定初始值。Struct类型的使用和Class使用是大同小异的。MyPoint()就相似于类的构造函数。咱们声明完变量,并分配内存空间后,咱们对x, y的值进行打印能够看到x, y的初始值为0。具体以下所示:htm
咱们能够调用访问权限为读写的setMyPoint()方法来改变结构体变量中属性的值,下方就是把坐标(10.0,20.0)赋值给myPoint变量,具体以下所示。对象
除了上述方法给结构体变量中的属性赋值外,咱们还能够经过构造函数给其属性赋值。也就是在给变量分配内存空间时为其指定初始值,这一点就和类的构造函数即为类似了。具体方式以下图片中的代码片断所示:
结构体就先聊到这儿,下面开始比较重要的部分:类(Class)
二. 类(Class)
Swift做为一门现代面向对象编程语言,怎么能没有类呢。关于Objc中的Class, 请参考我以前发表的一篇博客《在Objective-C中浅谈面向对象》, 其中浅谈了Objective-C中面向对象的东西。今天就聊聊Swift中的类,虽然语言不通,可是Class仍是大同小异的。本篇博客的此部分注重Swift类中的语法已经使用方式,对面向对象的思想没有作过多的陈述,由于咱们的重点是在Swift编程,而不是面向对象编程。好~进入这一部分的主题。
1. 类的建立与构造器
为了简单也是秉着由浅入深的原则,接下来将把上面MyPoint结构体类型使用类的形式来实现一下。简单从语法上看二者是大同小异的。下方截图中的代码段是在上述MyPoint结构体修改而来的。改为下方MyPoint类作了两点修改,第一点就是把struct关键字改为class关键字,
下方是MyPoint类的使用方法,虽然在上述类中没有构造函数,会自动生成一个默认的无参构造函数。以下所示,调用的就是默认的无参构造函数进行的类的实例化。由于在类定义时咱们为类中的属性(即类的特征)指定了初始值,因此将值进行打印就会显示初始值了。
你在类定义时,没有为其定义其余的构造函数,若是你调用了该未定义的构造函数,那么就是你的不对了,编译器就会报错了,以下所示:
接下来咱们就要为咱们的MyPoint()类建立构造函数了。与其余现代编程语言(如C++, C#,Java等)不一样,Swift的构造函数不是与类名同名的函数,而是使用特定的函数名init()来建立其构造函数。下方就是咱们MyPoint类的构造函数,函数名固然是init了。在构造函数的形参列表中,咱们能够为形参指定默认值,虽然下方只是一个构造函数,可是该构造函数与他的形参列表中的默认值一组合起来,可谓是打了一个漂亮的组合拳,使用起来也是灰常顺手的。
给构造函数的形参列表指定默认值就省去了重载构造函数的麻烦。上面添加了一个构造函数,并为各个形参指定默认值,下方是其不一样的调用方式,这在C++中应该重载4个构造函数才能实现的效果。Swift语言因而可知一斑呢~为之又眼前一亮,心中为之一振呢。具体调用方式以下:
2.对象的赋值与比较
在Swift中也是容许把一个类的变量的值经过赋值运算符(=)来赋值给另外一个变量的。不过有一点要搞明白,若是类变量a的值赋值被类变量b,那么变量a和b就指向同一块内存区域。若是a中的实例变量中的值进行了修改,那么实例b中的值也会进行修改。为了更好的表达这个思想,咱们仍是来张原理图来介绍一下对象的赋值吧。具体的原理图以下所示:
上面是原理,下方就是验证。咱们就声明两个变量a, b。 给a分配一个实例的空间,而后把a赋值给b。再接着就是改变a的值,观察b中的属性变化。具体以下所示:
若是要判断两个变量是否指向同一个实例,那么咱们就须要使用恒等运算符(===)了。下方就是判断a是否和b指向同一个内存空间,具体代码以下所示:
3.属性的懒加载(lazy)
在Swift的类中在对类进行初始化时,要对一些属性进行初始化。若是某些属性的初始化若是很是的耗费时间,那么在这种状况下咱们就能够该初始化耗时的属性声明为懒加载的属性。就是在该属性声明的时候加上lazy关键字。被Lazy关键字修饰的变量会在使用时才会进行空间的分配。下方就是一个lazy的实例。
在下方实例中,除了MyPoint类,咱们还须要定义一个MyCycle类。在MyCycle类中,使用到MyPoint类。在MyCycle类中的MyPoint属性为懒加载属性,具体请看代码,以下所示:
(1) 定义MyCycle类,在MyCycle类中,定义一个属性为lazy的MyPoint类变量。以下所示:
(2)接下来就是使用MyCycle, 声明MyCycle类型的变量,并为其分配MyCycle的类型实例。由下方实例可知,在调用MyCycle()构造函数时,MyCycle类中的point属性并无对其进行初始化,此刻的point为nil。这样就减小了MyCycle初始化的时间。
(3) lazy属性point会在MyCycle实例对象在使用point属性时才会对其进行初始化,下方是myCycle实例变量调用point属性的代码片断,这时就明确的看到point是不为nil的。以下所示:
4. 计算属性(Count Property)
计算属性这一个特性在Objective-C中也是没有的。什么是计算属性呢,一句话归纳:计算属性的值能够由其余属性的值来计算获得,同时在给计算属性赋值时也能够用来计算其余属性的值。也许提及来比较拗口,理解起来也许回有些困难,那么接下来来个小实例便可明白计算属性是怎么回事了。
下方咱们建立一个名为Money的类,在Money类中有两个属性,一个是存储属性(普通属性)名为CNY(表明着人民币), 另外一个是名为USD的计算属性(表明美圆)。在USD计算属性的set方法中由USD的值计算CNY的值,在USD计算属性的get方法中由CNY计算出USD的值,并返回。Money类的具体代码片断以下所示:
计算属性在使用时和存储属性没有什么区别,下方是Money实例来调用其存储属性和计算属性的代码段,已经结果输出以下所示。下方代码段虽然简单,可是你慢慢的去品仍是颇有味道的。先看第一部分,也就是第一次给USD赋值,当给USD赋值时,CNY的之会当即被计算出来。 而当咱们给CNY赋值时,USD的值不会被当即计算出来,由于只有在使用USD时才会调用get方法,这时候才会根据CNY的值来计算USD的值。具体结果请看下方代码段:
5. 属性观察
属性观察是用来干吗的呢?说白了,属性观测器就是来观察属性的赋值状况的,属性观测器包括willSet()和didSet , willSet在属性将要被赋值的时候被调用, didSet是在属性被赋值后调用,关于这两个属性观察函数,写个实例就一目了然了。由下方实例可知,在willSet调用时,property属性的值还为默认值,可是在didSet执行时,property的值已经成为被赋予的值了。
6. 实例方法与类方法
在Objc中,类方法是由+来修饰的,实例方法是由-号来修饰的。在Swift的方法中就没有+或者-号进行修饰了,可是Swift中声明方法时,多了一个class。普通方法没有什么特别之处,而类方法的声明和定义须要在关键字func前添加class关键字。下方MyTestClass中定义了一个实例方法和一个类方法,而且给出了调用方式,以下所示:
今天博客的内容就先到这儿,下篇博客会涉及一些类的继承和类中的方法和属性的访问权限等其余一些关于类的东西。