窥探 Swift 之别具一格的 Struct 和 Class
说到结构体和类,还是那句话,只要是接触过编程的小伙伴们对这两者并不陌生。但在Swift中的Struct和Class也有着令人眼前一亮的特性。Struct的功能变得更为强大,Class变的更为灵活。Struct中不仅可以定义属性,并且还可以在其中定义函数,这一点比较像Class的特性了。不过Struct毕竟是结构体,它还是不支持继承等类特有的属性的。今天这篇博客就正儿八经的来搞一搞Swift中的Struct和Class。
当然,这篇博客是比较基础的,但是基础的东西才是重要的东西呢,废话不多说了,走起。
一. Struct (结构体)
结构体,说白了就是一组变量,这些变量有统一的命名。在Swift中,我们不仅可以在Struct中声明变量并为变量设置默认值,而且可以在Struct中添加相应的函数。接下来我们就要创建一个Point结构体,里边有两个属性x坐标和y坐标,并且x坐标和y坐标的初始值为0。其中还有两个方法,一个是display方法,负责输出点的坐标,并且还有一个setPoint方法,这个方法负责设置坐标点。然后我们就要去这个结构体去声明变量,并且调用其中的方法。
1.结构体类型的定义
使用struct关键字来声明我们的结构体类型,结构体类型的名称为MyPoint, 其中坐标x, y为变量,其初始值为0。并且为我们的结构体添加了一个setMyPoint()方法和display()方法。
由上面的代码片段你也许会注意到在setMyPoint()方法关键字func前边多了一个mutating关键字。在Struct中的函数,默认(不添加mutating关键字)的函数对Struct中属性只有只读权限。如果你添加上mutating, 那么该函数就对属性持有读写的权限。
2.结构体类型变量的声明以及结构体函数的使用
接下来我们就利用上述“MyPoint”结构体类型来创建一个结构体类型变量。因为(x, y)值是有初始值的,所以在初始化结构体变量时不需要为其指定初始值。Struct类型的使用和Class使用是大同小异的。MyPoint()就类似于类的构造函数。我们声明完变量,并分配内存空间后,我们对x, y的值进行打印可以看到x, y的初始值为0。具体如下所示:
我们可以调用访问权限为读写的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中定义了一个实例方法和一个类方法,并且给出了调用方式,如下所示:
窥探 Swift 之别具一格的 Struct 和 Class的更多相关文章
- 窥探Swift之别具一格的Struct和Class
说到结构体和类,还是那句话,只要是接触过编程的小伙伴们对这两者并不陌生.但在Swift中的Struct和Class也有着令人眼前一亮的特性.Struct的功能变得更为强大,Class变的更为灵活.St ...
- 窥探Swift系列博客说明及其Swift版本间更新
Swift到目前为止仍在更新,每次更新都会推陈出新,一些Swift旧版本中的东西在新Swift中并不适用,而且新版本的Swift会添加新的功能.到目前为止,Swift为2.1版本.去年翻译的Swift ...
- 窥探Swift之类的继承与类的访问权限
上一篇博客<窥探Swift之别具一格的Struct和Class>的博客可谓是给Swift中的类开了个头.关于类的内容还有很多,今天就来搞一下类中的继承以及类的访问权限.说到类的继承,接触过 ...
- 窥探Swift编程之错误处理与异常抛出
在Swift 2.0版本中,Swift语言对其错误处理进行了新的设计,当然了,重新设计后的结果使得该错误处理系统用起来更爽.今天博客的主题就是系统的搞一下Swift中的错误处理,以及看一下Swift中 ...
- 窥探Swift之协议(Protocol)和委托代理(Delegate)回调的使用
协议与委托代理回调在之前的博客中也是经常提到和用到的在<Objective-C中的委托(代理)模式>和<iOS开发之窥探UICollectionViewController(四) - ...
- 窥探Swift编程之强大的Switch
之前初识Swift中的Switch语句时,真的是让人眼前一亮,Swift中Switch语句有好多特有而且特好用的功能.说到Switch, 只要是写过程序的小伙伴对Switch并不陌生.其在程序中的出镜 ...
- 窥探Swift之基本数据类型
在上一篇博客“窥探Swift编程之在Playground上尽情的玩耍”中介绍了如何使用Playground来学习Swift语言.本篇博客就使用Playground来窥探Swift语言.千里之行始于足下 ...
- 窥探Swift编程之在Playground上尽情的玩耍
自从苹果公司发布Swift的时候,Xcode上又多了一样新的东西---"Playground".Playground就像操场一样,可以供我们在代码的世界里尽情的玩耍,在本篇博客中就 ...
- 汇编窥探Swift String的底层
String(字符串),是所有编程语言中非常重要的成员,因此非常值得去深入研究.众所周知,字符串的本质是字符序列,由若干个字符组成.比如字符串 "iOS" 由 'i'.'O'.'S ...
随机推荐
- 从数据库中选取数据形成select标签
添加文章时用代码如下: <select name="NClass" id="NClass" class="sel"> <? ...
- MATLAB基础操作符与数据格式显示
1.冒号":" 基本使用如下: X=1:10:表示生成向量[1,2,3,4,5,6,7,8,9,10] X=J:i:k ;表示向量[j,j+i,j+2i,...,k]; A(:,j ...
- mac 安装 gensim包出错
安装时需要卸载scipy,结果显示 permission之类 加sudo也不行, 必须 得先disable 掉mac的SIP ,方法是重启系统 ,按住command+r ,进行recovers模式,然 ...
- GIS可视化——麻点图
一.引言 目前在客户端绘制POI(Point of Interest,兴趣点)的方式主要是div(Marker的形式).svg.canvas.VML(后边三种就是Vector Layer)几种方式,这 ...
- 转:maven2创建一个eclipse工程,设置M2_REPO
from: http://tonychanhoho.iteye.com/blog/1584324 M2_REPO是一个用来定义 maven 2仓库在硬盘中的存储位置,windows默认是C:\User ...
- 成功者的特点 VS 失败者的特点
- SAS中的自动变量
Sas自动变量:由数据步语句自动创建的. _n_ :观测序号: _error_:错误信息变量; _numeric_ :所有数值变量: _character_:所有字符变量; _all_:所有变量; f ...
- Android常用资源
Eclipse ADT http://developer.android.com/sdk/installing/installing-adt.html https://dl-ssl.google.co ...
- Android网络编程Socket【实例解析】
Socket 事实上和JavaWeb 里面的Socket一模一样 建立客服端,server端,server开一个port供客服端訪问 第一步创建server端:(这里把为了便于解说.把server端, ...
- java 匿名类和匿名方法
package com.test; interface product{ int getPrice(); } public class News { /** * @param args */ publ ...